Go Down

Topic: Casting Big Numbers... (Read 344 times) previous topic - next topic

Constantin

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?

majenko

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: [Select]

floatVar = (float)byteVar;


Or to cast a float as an integer:
Code: [Select]

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: [Select]

floatVar = (float)byteVar / (float)intVar;

robtillaart

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: [Select]
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: [Select]
bool bc_num2float(bc_num num, float *f)
{
 if (abs(bc_num) > MAXFLOAT) return false;
 ...
 f = ..;
 return true;
}

hopes this gets you started...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Constantin

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.

robtillaart

Cantabrigia in the UK or US?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Constantin

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

Go Up