14

I would like to store in a variable the mantisssa of a double

I have post a code to get the binary representation of a double : click here

What should I change to isolate the mantissa

Community
  • 1
  • 1
Guillaume Paris
  • 10,303
  • 14
  • 70
  • 145

4 Answers4

22

In <math.h>

double frexp (double value, int *exp)

decompose VALUE in exponent and mantissa.

double ldexp (double value, int exp)

does the reverse.

To get an integer value, you have to multiply the result of frexp by FLT_RADIX exponent DBL_MANT_DIG (those are availble in <float.h>. To store that in an integer variable, you also need to find an adequate type (often a 64 bits type)

If you want to handle the 128 bits long double some implementations provide, you need C99 frexpl to do the splitting and then you probably don't have an adequate integer type to store the full result.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
3

Many Linux systems have /usr/include/ieee754.h which defines bitfields for IEEE-format float, double and long double: you could trivially "port" it if necessary.

user541686
  • 205,094
  • 128
  • 528
  • 886
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
2

The code here is a bit dangerous in terms of portability, but here it is...

#include <cstdint>

float myFloat = 100;
int32_t mantissa1 =
    reinterpret_cast<int32_t&>(myFloat) & (((int32_t)1 << 24) - 1);

double myDouble = 100;
int64_t mantissa2 =
    reinterpret_cast<int64_t&>(myDouble) & (((int64_t)1 << 53) - 1);
user541686
  • 205,094
  • 128
  • 528
  • 886
  • Original poster asked for `double`. – Jan Hudec Apr 15 '11 at 06:11
  • 1
    @Jan: Oops, it said `float` in the title... I'll change it – user541686 Apr 15 '11 at 06:12
  • @Mehrdad : Easier to use cstdint's `uint32_t` and `uint64_t` and eliminate half of the assumptions. – ildjarn Apr 15 '11 at 06:16
  • @ildjarn: I thought about that at first but didn't bother, since I wasn't sure if it would be useful considering that I wasn't sure if `sizeof(float) == 4` anyway. But I'll change it, okay. – user541686 Apr 15 '11 at 06:17
  • @Mehrdad : Any platform with unusual sized types probably won't have cstdint anyway :-P – ildjarn Apr 15 '11 at 06:20
  • You'll need a `(1LL << 53)` on all platforms where `int` is less than 64 bits. – Lindydancer Apr 15 '11 at 07:00
  • Sorry, the comment wasn't registered. This doesn't work (did you try it, with 2?) as it doesn't take the implicit bit into account. – AProgrammer Apr 15 '11 at 08:02
  • @AProgrammer: Ah, no I admittedly didn't try it, thanks for the comment. But I don't believe that's an issue -- the implicit bit isn't part of the stored value, so I didn't imagine the OP wanted it. – user541686 Apr 15 '11 at 08:05
  • @AProgrammer: The implicit bit is not part of the mantissa field. If you wanted it to be included you should have explicitly stated so in the question. If you take that into account, you can simply add it using a simple *or* (after checking for special cases like subnormal numbers, inf etc.) – Lindydancer Apr 15 '11 at 08:07
-3

A stringify tokenizing approach:



    #include &ltstring.h&gt
    #include &ltstdio.h&gt

    long double example=(-10000.0/7.0);

    long long ldoubtollmant(long double num)
    { char stackdump1[101]={'\0'};
      char *dump1=&stackdump1[0];
      char stackdump2[101]={'\0'};
      char *dump2=&stackdump2[0];
      snprintf(dump1,100,"%.15Le",num);
      char *next1=dump1;
      next1=strtok(dump1,"e");
      char *next2=NULL;
      strtok_r(next1,".",&next2);
      snprintf(dump2,100,"%s%s",dump1,next2);
      return atoll(dump2);}

    short int ldoubtoshexp(long double num)
    { char stackdump1[101]={'\0'};
      char *dump1=&stackdump1[0];
      snprintf(dump1,100,"%.15Le",num);
      char *next1=NULL;
      strtok_r(dump1,"e",&next1);
      return (short int)atoi(next1);}

    int main(int argc,char *argv[])
    { printf("\n%lld",ldoubtollmant(example));
      printf("\n%hd",ldoubtoshexp(example));}
splugenbrau
  • 11
  • 1
  • 3