5

Converting from 0 10000101 01010011000000000000001 to decimal (which is 84.75000762939453125) works well:

FP: 0 10000101 01010011000000000000001
Fraction: (1.)01010011000000000000001
Exp 10000101: 133
Bias: 133-127=6
Moving by exp: 1010100.11000000000000001
Convert parts to decimal: 84.75000762939453125

Why I'm not able to do the same converting 0 00000001 00000000000000000000001 to decimal (which is (1.1754945E-38):

FP: 0 00000001 00000000000000000000001
Fraction: (1.)00000000000000000000001
Exp 00000001: 1
Bias: 1-127=-126
Moving by exp: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Convert parts to decimal: 0.?!?!?!

Can't get 1.1754945E-38 converting binary 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 to decimal.

Where am I wrong?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
markzzz
  • 47,390
  • 120
  • 299
  • 507

2 Answers2

2

Where am I wrong?

Couple of problems

Moving by exp incorrect

A 0 should be a 1.

FP: 0 00000001 00000000000000000000001
Fraction: (1.)00000000000000000000001
Exp 00000001: 1
Bias: 1-127=-126
// wrong
Moving by exp: 0.0000000000 (many zeros omitted) 0000000000000000000000000001
// should be 
Moving by exp: 0.0000000000 (many zeros omitted) 0000100000000000000000000001
//                                                   ^

Web site incorrect

OP's reference tool returns 0 for values as great as 0.000000000000000000000000000000000000000000000000000000000000000000012

Inputting 0.0000000000 (many zeros omitted) 0000100000000000000000000001 also reports 0.


A correct conversion of the string "0.0000000000 (many zeros omitted) 0000100000000000000000000001" as a base-2 fraction readily gives OP's expected value.

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

int main(void) {
  char *Moving_by_exp = "0."
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "00000100000000000000000000001";
  char *s = Moving_by_exp;
  double x = 0.0;
  int power2 = 0;
  while (*s) {
    power2--;
    if (*s == '.') power2 = 0;
    else x = x*2 + *s - '0';
    s++;
  }
  printf("%.7e\n", x*pow(2,power2));
  printf("%.16e\n", x*pow(2,power2));
}

Ouput

1.1754945e-38
1.1754944909521339e-38

OP's incorrect "0.0000000000 (many zeros omitted) 0000000000000000000000000001" converts to 1.4012985e-45

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thanks for the tip 1 (my error, now I see). Any tool online where I can test those binary conversion? Thanks anyway – markzzz Apr 27 '18 at 08:48
  • 1
    @markzzz I have used [IEEE-754 Floating Point Converter](https://www.h-schmidt.net/FloatConverter/IEEE754.html) without issue. Yet on-line tools are hard to automate testing. – chux - Reinstate Monica Apr 27 '18 at 13:16
0

You are not wrong. The tool is wrong.

I found one page (the first that came up when I googled "ieee 754 converter") that has no problems with your number: https://www.h-schmidt.net/FloatConverter/IEEE754.html

I wrote a small C program, which probably contains some unportability, undefined behaviour and obsolete coding practices, but which shows conversions between some relevant floats and ints:

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

typedef union {
  float f;
  int i;
} both;

void printbits(int k) {
  int i;
  for (i = 0; i < 32; i++) {
    if (i == 1 || i == 9)
      printf(" ");
    if (k & (1<<(31-i)))
      printf("1");
    else
      printf("0");
  }
  printf("\n");
}

int main() {

  printf("sizeof(float) = %ld\n", sizeof(float));
  printf("sizeof(int) = %ld\n", sizeof(int));

  both u;

  u.i = 0x00800001;
  printbits(u.i);
  printf("%g\n", u.f);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
  printf("\n");

  u.i = 0x00800000;
  printbits(u.i);
  printf("%g\n", u.f);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
  printf("\n");

  u.i = 0x007fffe1;
  printf("%g\n", u.f);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
  printf("\n");

  u.i = 0x42a98001;
  printf("%g\n", u.f);
  printf("%g\n", 84.75000762939453125);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
  printf("\n");

  u.f = 1.17549e-38;
  printbits(u.i);
  printf("%#010x\n", u.i);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));

  u.f = 1.1754944e-38;
  printbits(u.i);
  printf("%#010x\n", u.i);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));

  u.f = 1.1754945e-38;
  printbits(u.i);
  printf("%#010x\n", u.i);
  printf("%d %d\n", fpclassify(u.f), isnormal(u.f));

}

The output (on Ubuntu, compiled with gcc, processor x86) is:

sizeof(float) = 4
sizeof(int) = 4
0 00000001 00000000000000000000001
1.17549e-38
4 1

0 00000001 00000000000000000000000
1.17549e-38
4 1

1.17549e-38
3 0

84.75
84.75
4 1

0 00000000 11111111111111111100001
0x007fffe1
3 0
0 00000001 00000000000000000000000
0x00800000
4 1
Arndt Jonasson
  • 856
  • 1
  • 6
  • 14
  • I know the conversion is correct :) I use the same tool. My problem is convert (in decimal) this number: `0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001`. Mine is an academic question, to learn how conversion works. It should give to me 1.1754945E-38 as result, this binary to decimail... – markzzz Apr 26 '18 at 07:09
  • I don't understand. This number above is something you haven't mentioned before. I answered the question you asked. – Arndt Jonasson Apr 26 '18 at 12:14
  • That one doesn't have a decimal point. The connection with the rest of your question is not clear - I took it as being a somewhat muddled way of rephrasing the section before. – Arndt Jonasson Apr 26 '18 at 12:18
  • Mantissa become 00000000000000000000001 right? Than you need to multiply by e-126, right? Once you got it, you need to convert it to decimal. Right? – markzzz Apr 26 '18 at 12:20
  • I give up. What is the actual question? A web site tool? IEEE-754 as such? How to do it in a particular language? Please remove the smoke screens in the question. – Arndt Jonasson Apr 26 '18 at 12:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169863/discussion-between-markzzz-and-arndt-jonasson). – markzzz Apr 26 '18 at 13:33