Go Down

### Topic: Arbitrary precision (big number) library port for Arduino (Read 71996 times)previous topic - next topic

#### Pyrotrons #135
##### Dec 29, 2014, 03:04 amLast Edit: Dec 29, 2014, 03:05 am by Pyrotrons
Quote
You can cast a big number into a long, or get a character array returned.
Char array would be best, as my BigNumber output could potentially be a very small number (a few picofarads, 3x10E-12).

Quote
What do you want to do so many digits of precision?
I'm squaring two frequencies in the Mhz range, dividing them, subtracting 1.0 from the result, then multiplying by a capacitor value in the pF range.  Very big, to very small.

Code: [Select]
`  BigNumber X = F1;  //define the first frequency measurement    BigNumber Y = F2;  //define the second frequency measurement  BigNumber one = "1"; //don't laugh  BigNumber Cx = ((  ((X*X)/(Y*Y)) - one) * Ceff); `

• X and Y are frequency counts, each count is ~1 Megahertz, with Y being slightly lower than X.
• Ceff is a .000000000390 Farad "effective" reference capacitor value (390 picofarads).
• Cx is the capacitor being measured. The one I want the value of.

Quote
If you want help you need to post code, not just say that something, which you're not disclosing, did not compile.
You're absolutely right, I'll remove my statement above. I chose this due to my lack of converting confidence...didn't mean to point fingers, I won't do it again.

#### Pyrotrons #136
##### Dec 29, 2014, 03:36 am
I've reduced my problem to its simplest form...converting a BigNumber variable into a printable format (not speaking of Serial.println...).  See errors at bottom.  Regards,  - Pyrotrons

Code: [Select]
`#include <stdint.h>#include <BigNumber.h>#include <TouchScreen.h> #include <TFT.h>//Touchscreen setup:#ifdef MEGA  #define YP A2   // must be an analog pin, use "An" notation!  #define XM A1   // must be an analog pin, use "An" notation!  #define YM 54   // can be a digital pin, this is A0  #define XP 57   // can be a digital pin, this is A3 #endif void setup(){  Serial.begin(57600);  delay(100);  BigNumber::begin ();  //init BigNumber lib  BigNumber::setScale (15);  //set precision  Tft.init();  //init TFT lib  Tft.setDisplayDirect(UP2DOWN); //set text direction    String tempstr_A = "Big ol string to display";  //random stuff to test printing to TFT screen  char buf_A;  tempstr_A.toCharArray(buf_A, 15);   Tft.drawString(buf_A,220,20,2,WHITE);  //this works  BigNumber x = "44444444444444444444444444444";  BigNumber y = "2";  BigNumber z;  z = x * y;  Serial.println(z); // This works. I get 8888888...etc.//Beginning attempt at converting BigNumber variable "z" into a printable (on my display) format//----------------------------------------------------------------------------------------------  String tempstring = z;  //Error: "conversion from 'BigNumber' to nonscalar type 'String' requested  char buf_B;  z.toCharArray(buf_B, 20); //Error: 'class BigNumber has no member named 'toCharArray'} //END of setupvoid loop(){  while(1);}`

#### nickgammon #137
##### Dec 29, 2014, 04:35 am
To get the string from a big number just call the  toString function, eg.

Code: [Select]
`char * buf = z.toString ();// use buffree (buf);`

However why bother?

Just make sure that your end result is a number in pF can be expressed in a long.

You are not going to get a number with 10 digits in a picofarad range (that cannot be expressed in microfarads for example).
Please post technical questions on the forum, not by personal message. Thanks!

#### refsmmat #138
##### Jan 29, 2015, 10:08 pm
Hi,

Firstly, thanks Nick for the library.
I am using it on a DUE to implement an "astronomy" application.

I am parsing a csv & looking to transpose values from a char array into a bignumber. My intent is to run the Matlab model (link below) on a due to generate accurate planet positions wrt time.

My thought on the method is  -
1)using pointers, write the parsed char array containing the bignumber to a memory location
2) read the bignumber from the same location.

My questions are:
a) will this work?
b)is this the tidiest method?

My orig code  (in Matlab) is here:

http://au.mathworks.com/matlabcentral/fileexchange/26114-solar-system-model--planetary-n-body-modelling-

I can post the parsing elements(currently incomplete) here if it helps

Many thanks
Stephen

#### nickgammon #139
##### Jan 29, 2015, 10:44 pm
I can't say whether code that is merely described will work. You could post it. You could try it and see what happens which is what I usually do.
Please post technical questions on the forum, not by personal message. Thanks!

#### NiceAntoine #140
##### Feb 27, 2015, 03:48 am
I cannot figure how to use an external eeprom chip to go further with even bigger numbers , after all ram is the limiting factor, maybe using an eeprom chip as ram or assigning variables to it might help? any idea?

#### nickgammon #141
##### Feb 27, 2015, 04:04 amLast Edit: Feb 27, 2015, 04:04 am by Nick Gammon
I don't see how that would help. Get a chip with more RAM if you must.
Please post technical questions on the forum, not by personal message. Thanks!

#### NiceAntoine #142
##### Feb 27, 2015, 07:00 pm
I don't see how that would help. Get a chip with more RAM if you must.
After reading docs about how to efficiently make operations with big numbers, an authors said " normally you may use big numbers until your RAM is full, but if you are smart enough you can calculate big numbers until your RAM and your HDD are full."
After reading some math and programming info, I know how to proceed in order to use an SD card to go MUCH further with big numbers.
It will be great to have a project that allows our humble arduino UNO to do- for instance- 4096bit RSA encryption .
As soon as I finish an urgent work, I will for sure puts my hands on it.

I might be a newbie in programation, but numbers and me, we are good old friends !

By the way, if someone do the project , I will be happy to try to improve it.

Cheers!

#### flok99 #143
##### Sep 06, 2015, 10:38 pmLast Edit: Sep 06, 2015, 10:40 pm by flok99
I very much like this library and its c++ wrapper. There's only one thing: it uses so much memory. Not because of the code-size or that large numbers take large amounts of memory, but that it uses 1 byte to store 1 digit. That is over 50% waste (1 digit fits in less than 4 bits).
Maybe all accesses to each digit can be wrapped in a function which divides the index in the char by 2, then checks the original lsb if it was 0 or 1 and then picks the lower or upper nibble. Would use slightly more cpu but with the advantage of almost a doubling in memory efficiency.

p.s. @nick gammon: have you seen my patches at github?

#### nickgammon #144
##### Sep 06, 2015, 10:47 pm
Quote
...  it uses 1 byte to store 1 digit ...
As did the original library. I'm reluctant to fiddle too much, because I might introduce bugs without realizing it. Plus, some people would want speed more than memory compactness.

Quote
... have you seen my patches at github?
I got a pull request, yes. I have to take a little while to examine it. Thanks. Please post technical questions on the forum, not by personal message. Thanks!

#### odometer #145
##### Sep 07, 2015, 02:39 am
Maybe modify it so it uses base 100 instead of base 10?

#### odometer #146
##### Sep 07, 2015, 10:17 am
Char array would be best, as my BigNumber output could potentially be a very small number (a few picofarads, 3x10E-12).

I'm squaring two frequencies in the Mhz range, dividing them, subtracting 1.0 from the result, then multiplying by a capacitor value in the pF range.  Very big, to very small.

Code: [Select]
`  BigNumber X = F1;  //define the first frequency measurement    BigNumber Y = F2;  //define the second frequency measurement  BigNumber one = "1"; //don't laugh  BigNumber Cx = ((  ((X*X)/(Y*Y)) - one) * Ceff); `

• X and Y are frequency counts, each count is ~1 Megahertz, with Y being slightly lower than X.
• Ceff is a .000000000390 Farad "effective" reference capacitor value (390 picofarads).
• Cx is the capacitor being measured. The one I want the value of.

What datatype are F1 and F2?

With a bit of algebra, you might be able to do this well enough without BigNumber.

#### flok99 #147
##### Sep 09, 2015, 02:03 pmLast Edit: Sep 09, 2015, 02:11 pm by flok99
Maybe modify it so it uses base 100 instead of base 10?
That may nog work.

The number.h file says:

Code: [Select]
`/* The base used in storing the numbers in n_value above.   Currently this MUST be 10. */#define BASE 10`

Also a quick test shows that it doesn't work with other BASE values. In this test I tried BASE = 255.

Code: [Select]
`#include <stdint.h>#include <stdio.h>#include "BigNumber.h"int main(int argc, char *argv[]){ uint64_t i = 812389l * 181092947l; printf("%lu\n", i); BigNumber bn1(812389); BigNumber bn2(181092947); BigNumber bn = bn1 * bn2; long bnl = bn; printf("%ld\n", bnl); return 0;}`

Result:

Code: [Select]
`147117918120383132421247473087`

#### aarg #148
##### Sep 09, 2015, 02:10 pmLast Edit: Sep 09, 2015, 02:12 pm by aarg
Any reason why bignum calculations can not be done in binary? Conversion is too unwieldy? Mathematicians want truncation to be in decimal?
... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

#### odometer #149
##### Sep 09, 2015, 09:21 pmLast Edit: Sep 09, 2015, 11:21 pm by odometer Reason: mistake in denominator
I'm squaring two frequencies in the Mhz range, dividing them, subtracting 1.0 from the result, then multiplying by a capacitor value in the pF range.  Very big, to very small.

Code: [Select]
`  BigNumber X = F1;  //define the first frequency measurement    BigNumber Y = F2;  //define the second frequency measurement  BigNumber one = "1"; //don't laugh  BigNumber Cx = ((  ((X*X)/(Y*Y)) - one) * Ceff); `

• X and Y are frequency counts, each count is ~1 Megahertz, with Y being slightly lower than X.
• Ceff is a .000000000390 Farad "effective" reference capacitor value (390 picofarads).
• Cx is the capacitor being measured. The one I want the value of.

So try this:

Code: [Select]
`  float f2_f = F2;  // second frequency (we expect this to be lower)  float d_f  = (F1 - F2);  // difference between the two frequencies  float q_f  = (((2 * f2_f) + d_f) * d_f) / (f2_f * f2_f); // if my algebra is correct  float c_f  = q_f * 390.0; // capacitance in picofarads  `

The algebra I am using is:

(a+b)^2 = (a^2) + (2*a*b) + (b^2)
Therefore:
(a+b)^2 - (a^2) = (2*a*b) + (b^2) = ((2*a)+b)*b

Go Up