bson@rice-chex.ai.mit.edu (Jan Brittenson) (12/01/90)
I'm looking for a fairly portable way of extracting the exponent of a double, such that: (int) EXP_OF(1.2345e-17) == -17 Portability is more important than speed. Precision isn't of importance either, as the mantissa is handled separately. I'm using SunOS 4.1, and didn't find any clues at all as to how to accomplish this in the man pages. (I.e. no functions for dissecting doubles.) Use of pure <math.h>-declared functions/defined would be perfect. I guess one way would be to set the mantissa to 1 and return the log10. My aim is to generate 10's complement BCD-coded floating-point data in a cross assembler where ease of porting is the main objective. Doubles don't conform to the range of the BCD numbers, but that's not a big issue. For simplicity all floating-arithmetic is done in doubles, and are converted to BCD numbers only when generating data.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (12/03/90)
In article <12131@life.ai.mit.edu>, bson@rice-chex.ai.mit.edu (Jan Brittenson) writes: > I'm looking for a fairly portable way of extracting the exponent of > a double, such that: > (int) EXP_OF(1.2345e-17) == -17 > > I'm using SunOS 4.1, and didn't find any clues at all as to how to accomplish > this in the man pages. (I.e. no functions for dissecting doubles.) Use > of pure <math.h>-declared functions/defined would be perfect. I can tell from this that you didn't look at man floating_to_decimal which covers single_to_decimal(), double_to_decimal(), extended_to_decimal(). Those functions are not portable, but if you don't mind an #if in your program it would be silly not to avail yourself of correct rounding when you can get it. Also in the SunOS 4.1 manual pages is the ANSI C function frexp(): double frexp(double x, int *pexp) which returns y and sets *pexp such that y*2**(*pexp) == x and y .in. [1/2,1) or x == y == 0 which counts as "dissecting" a double in my book. The very simplest dodge is to exploit the fact that you apparently want a decimal exponent. Very well, what's wrong with sprintf()? #include <float.h> /* defines DBL_DIG */ #include <stdio.h> /* defines sprintf() */ #include <stdlib.h> /* defines atoi() */ int decimal_exponent(double x) { char buffer[sizeof "+1.E-99999" + DBL_DIG]; (void) sprintf(buffer, "%+.*e", DBL_DIG, x); return atoi(buffer + 3 + DBL_DIG); } Beware: I haven't tested that. -- I am not now and never have been a member of Mensa. -- Ariadne.