Pages: [1]   Go Down
 Author Topic: Casting Big Numbers...  (Read 156 times) 0 Members and 1 Guest are viewing this topic.
Peoples Republic of Cantabrigia
Offline
God Member
Karma: 6
Posts: 640
Arduino happiness
 « on: January 16, 2013, 11:38:27 am » Bigger Smaller Reset

Nick Gammon adapted an excellent library to allow the Arduino to break the shackles of large numbers. I happen to find the library super useful for things like solving quadratic equations with large numbers. However, I wonder how I can turn the output from the sub-routine (three floats that Nicks library calculates correctly) into standard floats. Similarly, if I want to use a byte as a multiplier in a BigNumber-based calculation, is there a way to cast that?
 Logged

UK
Offline
Edison Member
Karma: 50
Posts: 2457
What a host of balls she had seen: gaity, the brass buttons...
 « Reply #1 on: January 16, 2013, 01:59:20 pm » Bigger Smaller Reset

Casting in C is done by placing the desired type in front of the variable name in brackets.

e.g.,. to cast a byte as a float:

Code:
floatVar = (float)byteVar;

Or to cast a float as an integer:
Code:
intVar = (int)floatVar;

Of course, if the target type isn't big enough to contain all of the source type, then you may loose data.

It's especially useful in calculations:

Code:
floatVar = (float)byteVar / (float)intVar;
 Logged

Netherlands
Offline
Tesla Member
Karma: 100
Posts: 9548
In theory there is no difference between theory and practice, however in practice there are many...
 « Reply #2 on: January 16, 2013, 02:01:10 pm » Bigger Smaller Reset

As the code is open it should be possible to adapt, but you should test if the number fits into a float or in a long.

there exist - long bc_num2long (num) - which you can use as an example how to convert float.

Code:
long
bc_num2long (num)
bc_num num;
{
long val;
char *nptr;
int  index;

/* Extract the int value, ignore the fraction. */
val = 0;
nptr = num->n_value;
for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--)
val = val*BASE + *nptr++;

/* Check for overflow.  If overflow, return zero. */
if (index>0) val = 0;
if (val < 0) val = 0;

/* Return the value. */
if (num->n_sign == PLUS)
return (val);
else
return (-val);
}

From the code you see it is tried to convert the value and if it not succeeds it returns 0 - which is imho a bug in the interface as 0 is a valid long.
Better interface would be returning a bool indicating if the conversion worked.
For floats you could return the value INF or NAN if out of range .. nay better a bool.

snippet
Code:
bool bc_num2float(bc_num num, float *f)
{
if (abs(bc_num) > MAXFLOAT) return false;
...
f = ..;
return true;
}
hopes this gets you started...
 Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Peoples Republic of Cantabrigia
Offline
God Member
Karma: 6
Posts: 640
Arduino happiness
 « Reply #3 on: January 16, 2013, 02:24:57 pm » Bigger Smaller Reset

Hi guys and thanks for the responses!

I had no issues with turning these big numbers into ints or longs, but floats kept being unhappy. One workaround is to simply scale the number up (factor 1,000,000,000), turn it into a long, then do a long/long division with a float cast in front. Works like a charm. Of course, the only reason I get away with this kludge is that I know the numbers being scales to be less than 1. Thus, I do not exceed the allowable range for a long.
 Logged

Netherlands
Offline
Tesla Member
Karma: 100
Posts: 9548
In theory there is no difference between theory and practice, however in practice there are many...
 « Reply #4 on: January 16, 2013, 02:48:33 pm » Bigger Smaller Reset

Cantabrigia in the UK or US?
 Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Peoples Republic of Cantabrigia
Offline
God Member
Karma: 6
Posts: 640
Arduino happiness
 « Reply #5 on: January 16, 2013, 03:09:32 pm » Bigger Smaller Reset

Hi Rob, East Coast, USA... been to the other Cambridge... very different!
 Logged

 Pages: [1]   Go Up