Skip to content

Commit

Permalink
fix #22, sign of fractions + roman
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Nov 21, 2024
1 parent cf9b306 commit 1d60979
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 29 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.4.6] - 2024-11-21
- fix #22, negative fractions
- fix unofficial **toRoman()** for > 4888
- add support for negative sign for **toRoman()**
- changed parameter to signed **toRoman(int32_t value)**
- add unit tests
- update readme.md

## [0.4.5] - 2024-11-20
- add experimental **fraction()**
- add **print_fractions.ino** example
Expand Down
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data in a way not supported in the standard print library of the Arduino.
- **char \* toBytes()** returns a string in KB MB GB etc.
- **char \* hex()** returns hexadecimal output with **leading zeros** up to **uint64_t**.
- **char \* bin()** returns binary output with **leading zeros** up to **uint64_t**.
- **char \* toRoman()** returns a ROMAN representation of a (positive) number.
- **char \* toRoman()** returns a ROMAN representation of a number.
- **char \* printInch(float inch, uint16_t step)** returns a string e.g. 5 7/8".
- **char \* printFeet(float feet)** returns a string e.g. 7"4'
- **char \* csi()** returns a comma separated integer for readability e.g. 3,254,152.
Expand Down Expand Up @@ -137,17 +137,33 @@ These will all be shown in UPPERCASE so KB, MB etc.
| exabytes | EB | 1024^6 | udabytes | UB | 1024^12 |


Treda Byte is shortened as "TDB" and uses 2 chars to indicate the magnitude.
#### Bigger

Treda Byte is officially shortened as "TDB" and uses 2 chars to indicate the magnitude.
That would take extra memory or slightly more complex code.
As it is very seldom used, "official" support stops with UDA.
Should be big enough for some time.

Note: max uint64_t == 2^64 is in the order of exa or zetta bytes.

To have some support for the really big sizes the code uses lowercase for the next 8 levels:
treda sorta rinta quexa pepta ocha nena minga luma (1024\^13 ~~ 1024\^21)
To enable this patch the function in the **printHelpers.cpp** file.

| Unit | abbrev. | size |
|:-----------:|:---------:|:---------:|
| tredabytes | tB | 1024^13 |
| sortabytes | sB | 1024^14 |
| rintabytes | rB | 1024^15 |
| quexabytes | qB | 1024^16 |
| peptabytes | pB | 1024^17 |
| ochabytes | oB | 1024^18 |
| nenabytes | nB | 1024^19 |
| mingabytes | mB | 1024^20 |
| lumabytes | lB | 1024^21 |

Note that from the ZETTA prefix all higher prefixes are starting with the
previous letter of the alphabet ZYXWVUtsrqponml


### hex() bin()

Expand Down Expand Up @@ -186,7 +202,7 @@ A less used but well known print format are the Roman digits.
The library function **toRoman()** will convert any number from 0..100 million into a Roman number.
The numbers 1..5000 ("official" range) are the well known UPPER case characters.

- **char \* toRoman(uint32_t value)** returns Roman string.
- **char \* toRoman(int32_t value)** returns Roman string.

| char | unit | notes |
|:------:|:-------|:------------|
Expand All @@ -205,7 +221,6 @@ Note: The maximum length returned is 16 characters in the "official" supported r

Notes:
- value == 0 => N is not part of the "official" numbers but we need it.
- values < 0 are not supported (note parameter is unsigned)
- values between 5K-10K are extended with extra M chars.
- values 10K-100M are represented with lower case characters.
This is not a standard, but it sort of works well.
Expand All @@ -216,6 +231,8 @@ Notes:
although IV would be (more?) correct and therefore IV is used.
The reason for IIII is that it is opposite of VIII giving a visual balance.

Since 0.4.6 negative numbers will have a - sign in front.


### Distance feet inch

Expand Down Expand Up @@ -314,12 +331,13 @@ When functions are added, the recommended minimum size might increase.
#### Must

- check TODO's in the code
- documentation

#### Should

- documentation
- improve readability of the code
- em ==> exponentFactor?
- extend unit tests

#### Could

Expand All @@ -332,8 +350,6 @@ When functions are added, the recommended minimum size might increase.
- pass char buffer as parameter (breaking)
- could be the log10 pow version?
- optimize **char \* hex(uint8_t / uint16_t ...)**
- negative ROMAN numbers (add a - sign)


#### Wont

Expand Down
11 changes: 10 additions & 1 deletion examples/print_toRoman/print_toRoman.ino
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,16 @@ void setup()
stop = micros();
Serial.println((stop - start) / 5000.0);
Serial.println(b);
delay(1000);
delay(100);

// unofficial romans
start = micros();
b = toRoman(12345678);
stop = micros();
Serial.println();
Serial.println(stop - start);
Serial.println(b);
delay(100);

// for (int i = 1; i <= 5000; i++)
// {
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/printHelpers"
},
"version": "0.4.5",
"version": "0.4.6",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=printHelpers
version=0.4.5
version=0.4.6
author=Rob Tillaart <[email protected]>
maintainer=Rob Tillaart <[email protected]>
sentence=Arduino library to help formatting data for printing. 64 bit integers (base 10 and 16). Engineering and scientific notation.
Expand Down
36 changes: 21 additions & 15 deletions printHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FILE: printHelpers.cpp
// AUTHOR: Rob Tillaart
// DATE: 2018-01-21
// VERSION: 0.4.5
// VERSION: 0.4.6
// PURPOSE: Arduino library to help formatting for printing.
// URL: https://github.com/RobTillaart/printHelpers

Expand Down Expand Up @@ -421,36 +421,41 @@ char * bin(uint8_t value, uint8_t digits) { return bin((uint32_t) value, digits
// extended with 10K units generated with the same but lower case chars.
// would expect a special char for 5000?
// need investigation.
char * toRoman(uint32_t value)
char * toRoman(int32_t value)
{
char * buffer = __printbuffer;
uint32_t val = value;
char * buffer = __printbuffer;
int32_t val = value;
uint16_t n[13] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
char roman[13][3] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };

buffer[0] = 0;
int idx = 0;
if (value == 0)
if (val == 0)
{
strcat(buffer, "N"); // NULL
return buffer;
}

if (value > 100000000UL)
// handle negative values
if (val < 0)
{
strcat(buffer, "-");
val = -val;
}
if (val > 100000000L)
{
strcat(buffer, "OVF"); // overflow
return buffer;
}

if (val >= 10000UL)
if (val >= 10000L)
{
// 10K units
while(val >= 10000UL)
while(val >= 10000L)
{
while (val >= (10000UL * n[idx]))
while (val >= (10000L * n[idx]))
{
strcat(buffer, roman[idx]);
val -= (10000UL * n[idx]);
val -= (10000L * n[idx]);
};
idx++;
}
Expand All @@ -460,7 +465,8 @@ char * toRoman(uint32_t value)
buffer[i] = tolower(buffer[i]);
}
}

// reset index
idx = 0;
// Official part UPPER case letters
while(val > 0)
{
Expand Down Expand Up @@ -776,16 +782,16 @@ char * fraction(double value)
// ESP32 does not support %ld or ltoa()
sprintf(buffer, "-%d/%d", highN, highD);
#else
sprintf(buffer, "%ld/%ld", highN, highD);
sprintf(buffer, "-%ld/%ld", highN, highD);
#endif
}
else
{
#if defined(ESP32)
// ESP32 does not support %ld or ltoa()
sprintf(buffer, "-%d/%d", highN, highD);
sprintf(buffer, "%d/%d", highN, highD);
#else
sprintf(buffer, "-%ld/%ld", highN, highD);
sprintf(buffer, "%ld/%ld", highN, highD);
#endif
}
return buffer;
Expand Down
4 changes: 2 additions & 2 deletions printHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// FILE: printHelpers.h
// AUTHOR: Rob Tillaart
// DATE: 2018-01-21
// VERSION: 0.4.5
// VERSION: 0.4.6
// PURPOSE: Arduino library to help formatting for printing.
// URL: https://github.com/RobTillaart/printHelpers

Expand Down Expand Up @@ -106,7 +106,7 @@ char * bin(uint8_t value, uint8_t digits = 8);
//
// value should be in range 1..9999
// values 10K-100M are experimental in lower case (see readme.md)
char * toRoman(uint32_t value);
char * toRoman(int32_t value);


////////////////////////////////////////////////////////////
Expand Down
26 changes: 25 additions & 1 deletion test/unit_test_001.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,32 @@ unittest(test_toRoman_standard)

unittest(test_toRoman_extended)
{
// zero test
assertEqual(0, strcmp("N", toRoman(0)) );
assertEqual(0, strcmp("OVF", toRoman(100000001UL)) );
// overflow
assertEqual(0, strcmp("OVF", toRoman(100000001L)) );
assertEqual(0, strcmp("-OVF", toRoman(-100000001L)) );
// negative
assertEqual(0, strcmp("-MCCXXXIV", toRoman(-1234)));

// large
assertEqual(0, strcmp("cxxiiiMMMMDLXVII", toRoman(1234567)));
}


unittest(test_fraction)
{
// positive
assertEqual(0, strcmp("59/469", fraction(0.1258)) );

// zero
assertEqual(0, strcmp("0/1", fraction(0)) );

// negative
assertEqual(0, strcmp("-59/469", fraction(-0.1258)) );

// fixed denumerator
assertEqual(0, strcmp("1/8", fraction(0.1258, 8)) );
}


Expand Down

0 comments on commit 1d60979

Please sign in to comment.