Big Numbers and how to print them

Status
Not open for further replies.

Constantin

Well-known member
As a 32-bit microprocessor, the Teensy 3.0 can handle much bigger numbers than the Arduino can without the addition of Nick Gammons excellent BigNumbers library. However, BigNumbers doesn't yet work on the Teensy ARM (compiler error with every example).

Understandably, the standard Serial.print command seems to be unhappy with printing anything bigger than 2^32 because that's the biggest number that one can easily define in the IDE (2^64 is available but cannot be printed with default commands...)

How does one print larger numbers than 2^64 when the IDE Serial.print command is limited to 2^32 bits only? Write one's own serial print command or appropriate parts of Nick Gammons code? Just wondering... Many thanks and have a great weekend.
 
32 bit and 2^32 are irrelevant in this case - it seems to be a binary coded decimal library, so each digit is 8 bits and you can have as many digits as you can fit (and process, and convert to strings) in memory.

http://en.wikipedia.org/wiki/Binary_coded_decimal

Obviously, as with any non-standard type, Serial.print won't know how to print it unless extended to do so. But Serial.print can print character strings just fine, so convery bcd to a string and print that.
 
Confirming that Teensy 3.0 gives compile errors with the BigNumbers library. Using the 'Powers' example supplied with the library:

Code:
f:/arduino/arduino-1.0.3-teensy-beta10/hardware/tools/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/lib/thumb2\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text+0x1c): undefined reference to `_exit'
collect2: ld returned 1 exit status

The same example compiles and runs without error on Teensy 2.0. Tail end of output from 'Powers':

Code:
3^296 = 1690018259982572543102790461507263160079798711423918968783706050350234533055544155479014890810974585040129437538246840034734725095872787340321
3^297 = 5070054779947717629308371384521789480239396134271756906351118151050703599166632466437044672432923755120388312614740520104204175287618362020963
3^298 = 15210164339843152887925114153565368440718188402815270719053354453152110797499897399311134017298771265361164937844221560312612525862855086062889
3^299 = 45630493019529458663775342460696105322154565208445812157160063359456332392499692197933402051896313796083494813532664680937837577588565258188667
3^300 = 136891479058588375991326027382088315966463695625337436471480190078368997177499076593800206155688941388250484440597994042813512732765695774566001
 
Last edited:
As another point of comparison, using Arduino 1.5 (original release) and Arduino Due, the BigNumbers example 'Powers' compiles and runs correctly (once I remembered to set the baud rate in the serial monitor :) ).

So this is not necessarily an AVR vs. ARM issue and not necessarily a fault in the ARM gcc standard C library, otherwise Due would also be affected.

(Oops, forgot to mention that the Teensy 2.0 and 3.0 tests were done with beta 10 Teensyduino).
 
I've added _exit() to mk20dx128.c. A copy is attached. Just rename from .txt to .c and replace the mk20dx128.c in hardware/teensy/cores/teensy3.

This will be in beta 11, which I'm planning to release very soon (only the new toolchain and bug fixes, like this one).

I ran the BigNumber Powers example on a Teensy 3.0 and it seems to work.
 

Attachments

  • mk20dx128.txt
    11.6 KB · Views: 259
Thank you!

32 bit and 2^32 are irrelevant in this case - it seems to be a binary coded decimal library, so each digit is 8 bits and you can have as many digits as you can fit (and process, and convert to strings) in memory.

http://en.wikipedia.org/wiki/Binary_coded_decimal

Obviously, as with any non-standard type, Serial.print won't know how to print it unless extended to do so. But Serial.print can print character strings just fine, so convery bcd to a string and print that.

True enough, but for someone as new to Arduinos and programming in general, it's hard to write a function like Nick did to handle printing large numbers. I'm OK re: logic, math, all that but the nuances of how functions interpret what they need to print, etc. is sometimes lost on me. Also, there is a huge difference between the 8-bit Arduino and a 32-bit ARM processor in that the latter can handle much larger numbers just fine while the Arduino needs the bignumbers library. The IDE still needs to catch up, as best as I can tell, to reflect the much greater range of variables that might be thrown at Serial.print, for example.

For my application, I use a least squares approach to help correct the INL and other imperfections of my ADC. The best fit correction for the data requires a function ax^2+bx+c and solving for that requires a number of summations, multiplications, etc. that result in very large numbers when exhausting the range of a 16 bit ADC. I don't recall the details offhand right now, but the largest number within that series of equations is something in the vicinity of 1.9x10^25 (resulting from sum_x^3*sum_x^4, IIRC).

In excel, I was able to correct offsets, INL, etc. to a very small number indeed, making the DAQ system the smallest contributor to variability. On the Arduino, even a uint64 couldn't come close to hacking the numbers above and I had to right-shift all inputs into the correction formula by 6 bits, resulting in much lower accuracy re: the correction factors. Bignumbers came to the rescue, though on a 32-bit microprocessor, bignumbers is not needed - it can handle them just fine. Just not all the other parts of the IDE!
 
Thank you, Paul!

I create nothing but trouble, it seems! ;) Do you suppose that the Arduino IDE will be re-written to allow the Due and so on to Serial.print larger numbers than is presently the case?
 
I create nothing but trouble, it seems! ;)

Reproducible bug reports are always very welcome! :)

Thanks!

Do you suppose that the Arduino IDE will be re-written to allow the Due and so on to Serial.print larger numbers than is presently the case?

I believe there's 2 ways to look at this question....

#1: Arduino does have an (obscure) interface for classes like BigNumber to print. I've modified BigNumber to use it. The code is attached. I modified the Factorials example to show how it's used. You can just pass a BigNumber object to Serial.print(), or any of the Arduino XYZ.print() functions.

#2: Inside the print function, floating point numbers are printed by shifting the integer portion of the mantissa into a 32 bit integer. The unsigned integer code is used to print the left side. Then a simple loop generates 8 digits from the fractional portion. This is relatively fast and doesn't require a lot of code, but the downside is you only get a printable range of approx 10e-7 to 10e9. Single precision float's range is approx 10e-44 to 10e38, but code capable of formatting numbers over that entire range is much larger and much slower. The decision was made to trade range for speed and small size.
 

Attachments

  • BigNumber_print.zip
    28.5 KB · Views: 229
Absolutely. Does serial.Print in Arduino 1.5 feature the ability to handle larger numbers than it did as of 1.03? That is, without requiring an external library like big numbers.... Seems like a pretty standard problem given how big a long long integer can get on a 32 bit microprocessor.
 
Absolutely. Does serial.Print in Arduino 1.5 feature the ability to handle larger numbers than it did as of 1.03? That is, without requiring an external library like big numbers.... Seems like a pretty standard problem given how big a long long integer can get on a 32 bit microprocessor.

Do you really need big INTEGERS ? can't you use floating point & sprintf().
 
Reproducible bug reports are always very welcome! :)
#1: Arduino does have an (obscure) interface for classes like BigNumber to print. I've modified BigNumber to use it. The code is attached. I modified the Factorials example to show how it's used. You can just pass a BigNumber object to Serial.print(), or any of the Arduino XYZ.print() functions.

Paul, did you tell Nick Gammon about tha useful modification? He might want to update the library on his site.
 
I have not. I didn't see an obvious way to contact Nick... and then I got distracted by the WS2811 LEDs ;-)

(and today I'm looking at the missing USB types....)

If you know a way to contact Nick, could you please let him know?
 
Status
Not open for further replies.
Back
Top