-1

I'm solving a question on online judge: https://acm.cs.nthu.edu.tw/problem/12237/

I need to represent IEEE-754 floating number with binary represent.

Here's my code:

#include <stdio.h>

void binaryprint();

int main(){
    float x;
    while(scanf("%f",&x) != EOF){                //File end with EOF
        unsigned int y = *(unsigned int*)&x;
        if(x == 0){                                  // INput = 0 -> 0*32
            for(int i = 0 ; i < 32 ; i++){
                printf("%d",0);
            }
        }
        else {
            if(x > 0) printf("%d",0);     //0 means positive but I find c will not print it out
            binaryprint(y);              //transfer to binary represent
        }
        printf("\n");
    }
}

void binaryprint(unsigned int x){
    if(x != 1){
        binaryprint(x/2);
        printf("%d",x%2);
    }
    else{
        printf("%d",1);
    }
}

But I got few wrong answer and because of I didn't know the testcase , I can't find out if there's any exception lead to the wrong answer. Thanks for your help!

王柏智
  • 1
  • 1
  • 2
    Make up your own test data, to the limits given in the problem. Watch out for corner cases. – Weather Vane May 20 '20 at 13:24
  • The range of the floating point number is -10^20 ~ 10^20 , and I've tried them https://www.h-schmidt.net/FloatConverter/IEEE754.html and it's same as my program T_T – 王柏智 May 20 '20 at 13:48
  • When the input number is sub-normal, your code fails. You need a simpler way to convert to binary output, non-recursive (that's a "school exercise" method), for exactly 32 bits. – Weather Vane May 20 '20 at 14:13
  • The binary output is faulty in other cases too, but it "happens to work" for the sample data given. Also you have a non-compliant function prototype `void binaryprint();` – Weather Vane May 20 '20 at 14:27
  • ! I found when my input is between 0~2 , it will only print 31bit and I need to print another "0" but I'm curious why – 王柏智 May 20 '20 at 14:35
  • As it happens, the smaller the number, the fewer bits it prints. Just iterate a mask along 32 bits, `for(unsigned m = 0x80000000; m != 0; m >>= 1)` Never use a recursive solution when you can use a simple iterative one. – Weather Vane May 20 '20 at 14:37
  • Oh , I calculate one time myself , if x<2 the exponent will be 127(+0) , and can't fulfill 8 bits(at least 128) so I need to print another "0" :D – 王柏智 May 20 '20 at 14:49
  • The smallest number I tried only printed 2 digits :) Just use a different algorithm (and not one that suppresses leading or trailing zeros, for example). – Weather Vane May 20 '20 at 14:51
  • OK!! Thank you very much! Actually I used recursive only because I didn't need to reverse it ( I think it is necessary to reverse the print if using for() ?) – 王柏智 May 20 '20 at 14:54
  • Not with the loop I suggested. it works from bit 31. – Weather Vane May 20 '20 at 14:55

1 Answers1

0

Here is a some program, with explanations in comments, that handles the cases shown. (It does not handle infinities or NaNs.)

#include <math.h>
#include <stdio.h>

int main(void)
{
    float x;
    while (scanf("%f", &x) == 1)
    {
        //  Print the sign bit.
        putchar('0' + (x < 0));
        if (x < 0)
            x = -x;

        /*  Multiply or divide x by two to get a significand in the interval
            [1, 2).  At the same time, count the operations to figure what
            power of two (in Exponent) is needed to scale that significand to
            the original value of x.
        */
        int Exponent = 0;
        while (x < 1)
        {
            Exponent -= 1;
            //  If we reach the subnormal range, stop.
            if (Exponent < -126)
                break;
            x *= 2;
        }
        while (2 <= x)
        {
            Exponent += 1;
            x /= 2;
        }

        /*  Encode the exponent by adding the bias of the IEEE-754 binary32
            format.
        */
        Exponent += 127;

        //  Print the seven bits of the exponent encoding.
        for (int i = 7; 0 <= i; --i)
            putchar('0' + (Exponent >> i & 1));

        /*  Skip the leading bit of the significand and print the 23 trailing
            bits.
        */
        x -= (int) x;
        for (int i = 0; i < 23; ++i)
        {
            x *= 2;
            int bit = x;
            x -= bit;
            putchar('0' + bit);
        }

        putchar('\n');
    }
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312