1

I am trying to do a program to convert decimals to floating point binary number but I can't seem to store the binary scientific notation inside a variable. So far I only can print the binary in scientific notation using %e, is there anyway to store this print value into a variable? Because want to use this variable to do my mantissa.

This is the code to print:

printf("\nExponent: %e", fraBinary);

fraBinary refers to my binary in floating format.

for example:

fraBinary = 1010.011001

print out in scientific notation = 1.010011001

i want to store this 1.010011001 into a variable so that i can use this variable in other parts of my program.

This is C program.

Domi
  • 27
  • 4
  • 2
    You can store a string representation of your number using `sprintf`. Hope it helps. – n. m. could be an AI Nov 07 '21 at 20:58
  • What about this: https://stackoverflow.com/questions/46339320/getting-exponent-of-a-floating-number-in-c https://stackoverflow.com/questions/42015544/how-can-i-extract-the-biased-exponent-from-a-floating-point-number-in-c https://stackoverflow.com/questions/15685181/how-to-get-the-sign-mantissa-and-exponent-of-a-floating-point-number https://stackoverflow.com/questions/22159832/getting-the-exponent-of-a-floating-number-in-c – Jerry Jeremiah Nov 07 '21 at 21:00
  • Most of the time, your C compiler and library do all the work here for you. Can you be a bit more clear about what you mean by "convert decimals to floating point binary number" and "use this variable to do my mantissa"? Me, when I type in a decimal number, some combination of my C compiler, and standard library functions like `atof`, take care of converting them to internal binary representations for me. – Steve Summit Nov 08 '21 at 04:35
  • hi @SteveSummit oh, I am supposed to do a C program to convert fractional decimals to 32-bit floating binary format. I did the divisions and multiplications calculation to convert already but I just need to display the binary in the sign exponent mantissa format. But I just found out from others that I have been handling what I assumed was binary as decimals so I technically did not convert the decimals to binary form. – Domi Nov 08 '21 at 10:46
  • @Domi Does your exercise come with some extra restrictions? Because the straightforward way to convert a decimal fraction to a 32-bit `float` is with a single, simple call to `atof`. Printing it back out in binary, significand+exponent format is definitely trickier, though. I'd start with `frexp`, as others have suggested. – Steve Summit Nov 08 '21 at 13:47

3 Answers3

1

Although C's floating-point types float and double typically use binary representations internally (almost invariably using formats conforming to IEEE-754), there are no standard routines for printing floating-point numbers in binary, or to convert binary strings to floating-point.

Basically there is almost no need for human-readable binary floating-point strings; floating-point numbers are almost always converted to and from decimal strings. (This can cause certain problems, though, since binary and decimal fractions are incommensurate, and almost always end up being imprecise approximations for each other — but that's a different story.)

The closest you can come to a binary floating-point string involves the %a format, although it's hexadecimal, not binary. But %a with printf will convert a floating-point number to a hexadecimal string, and %a with scanf will convert that sort of hexadecimal string back to a floating-point number.

It is probably easier to explain all this by example. Suppose I have the decimal number 12345.53125, and suppose I store it in a float variable:

float f = 12345.53125;

I can print it back out using %e or %f:

printf("%e\n", f);
printf("%f\n", f);

This prints

1.234553e+04
12345.531250

If I print it out using %a I get the rather odd-looking

0x1.81cc4p+13

Internally (in IEEE-754 single-precision floating-point) the number 12345.53125 is represented by a bit pattern which in hexadecimal is 0x4640e620, consisting of a 23-bit raw significand 0x40e620 and an 8-bit raw exponent 140. Shifting, applying the implicit "1" bit, and removing the exponent bias of 127, these work out to 0x1.81cc4 with an exponent of 13, which nicely matches %a's output.

In actual binary this number is

0b11000000111001.10001

or if you want an exponential notation it might be

0b1.100000011100110001e13

But, as I said, there's no built-in C function that will generate binary representations like that for you automatically.

If you did something like

double fraBinary = 1010.011001;
printf("%.9e\n", fraBinary);

and saw

1.010011001e+03

then you were not working with binary numbers at all: those numbers 1010.011001 and 1.010011001e+03 you saw and typed were pure decimal.


When you're working with ordinary floating-point numbers (using scientific notation or not), you don't usually need to worry too much about the binary representation (other than to know that it's there), and you don't usually have to work with significands ("mantissas") and exponents separately. If you don't already, you should know that the notation exemplified by

1.234553e+04

is almost universal. You can enter constants in your program that way:

double d = 1.234553e+04;

You can scan numbers from the user that way. You can take strings like "1.234553e+04" and convert them to float or double by calling the library functions atof() or strtod(). And as you know you can print them out (in decimal) using printf and %f or %e.

So what is it exactly that you want to do with your significands and/or exponents, in binary?

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • hi, so I can continue working with like the decimal version and then i put it in as a string before using the library functions as you mentioned? – Domi Nov 08 '21 at 04:44
  • because what my program is doing now is asking the user to input a fractional decimal and then my program will convert this decimal number into a floating binary format – Domi Nov 08 '21 at 04:48
  • @Domi You can easily (using standard library functions) read a decimal fraction string (scientific notation or not) and have it converted into a binary floating-point number (`float` or `double`), and you can easily take that binary floating-point number and print it back out as a decimal fraction string (scientific notation or not). Anything else is likely to be substantially trickier. – Steve Summit Nov 08 '21 at 15:45
0

You might want the stdlib function frexp -- it will return the mantissa and exponent of any floating point number:

#include <math.h>

double val = ... something
int exp;
double mant = frexp(val, &exp);
printf("%f is %f * 2^%d\n", val, mant, exp);

Note that the mantissa will always have an absolute value in the range [0.5,1.0), so in your case you might want to multiply it by 2.


Unclear from your question, but you might also be asking how to print a number in binary ascii. The standard library does not provide any way to do that, so you need to do it manually, converting the number into a sequence of 0/1 digits. You can do that with frexp and repeatedly doubling the number.

void binary_double(double v, FILE *fp) {
    int exp;
    v = frexp(v, &exp);
    if (v < 0) {
        fputc('-', fp);
        v = -v; }
    if (v == 0.0) {
        fputc('0', fp);
    } else if (v <= 1.0) {
        if (exp <= 0) {
            fputc('.', fp);
            while (exp++ < 0) ​fputc('0', fp); }
        while (v > 0 || exp > 0) {
            v *= 2;
            if (v >= 1.0) {
                fputc('1', fp);
                v -= 1.0;
            } else {
                fputc('0', fp); }
            if (exp > 0) {
                if (--exp == 0) fputc('.', fp); } }
    } else if (v != 0.0) {
        fputs("Inf", fp);
    } else {
        fputs("Nan", fp); }
}

A small modification to this could output in scientific notation.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • The preferred term for the fraction portion of a floating-point number is “significand,” not “mantissa.” “Mantissa” is an old word for the fraction portion of a logarithm. Mantissas are logarithmic (adding to a mantissa multiplies the number represented) while significands are linear (adding to a significand adds to the number represented). The returned fraction is not in [½, 1) when the input value is zero, and it is likely not (is unspecified by the C standard) when the input value is an infinity or NaN. – Eric Postpischil Nov 07 '21 at 23:21
  • (Theoretically, in a C implementation with a `double` in which the exponent range exceeded the `int` range, `frexp` could also have unspecified results for finite values.) – Eric Postpischil Nov 07 '21 at 23:23
  • i tried this code but it doesn't seem to help because they displayed some decimals instead, but I just want a binary output as shown in the example scenario I suggested in my question – Domi Nov 08 '21 at 02:33
0

is there anyway to store this print value into a variable?

To print a double as a string into a char array for later processing, use snprintf() and specify an ample precision for double to print DBL_DECIMAL_DIG digits. DBL_DECIMAL_DIG is the digits needed to well distinguish all double.:

#include <float.h>
// Make a big enough buffer
//         - d .  dddddd...dddddddd  e - eeee \0
#define N (1+1+1+(DBL_DECIMAL_DIG-1)+1+1 + 4 + 1) 
char buffer[N];
snprintf(buffer, sizeof buffer "%.*e", DBL_DECIMAL_DIG, some_double);

So far I only can print the binary in scientific notation using %e

This is strange as "%e" is used to print a decimal, not binary, value in scientific notation.


Code could use "%a" to print the double with a hexadecimal significand and a power-of-2 exponent in decimal.

This is the closest to directly printing in binary available via the standard library.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256