www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Separate Printing Mantissa and Exponent of a Floating Point

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
Is there a way to separately stringify/print the mantissa and 
exponent of a floating point?

I want this in my pretty-printing module to produce something like

1.2 \cdot 10^3

instead of

1.2e3

I could of course always split on the e but that is kind of 
non-elegant, I believe.
Aug 11 2014
next sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
Here's my current try:

string toMathML(T)(T x)  trusted /** pure */ if 
(isFloatingPoint!T)
{
     import std.conv: to;
     import std.algorithm: findSplit; //
     immutable parts = to!string(x).findSplit("e");
     if (parts[2].length == 0)
         return parts[0];
     else
         return parts[0] ~ "*10^" ~ parts[2];
}
Aug 11 2014
parent reply "Dominikus Dittes Scherkl" writes:
On Monday, 11 August 2014 at 14:15:05 UTC, Nordlöw wrote:
 Here's my current try:

 string toMathML(T)(T x)  trusted /** pure */ if 
 (isFloatingPoint!T)
 {
     import std.conv: to;
     import std.algorithm: findSplit; //
     immutable parts = to!string(x).findSplit("e");
     if (parts[2].length == 0)
         return parts[0];
     else
         return parts[0] ~ "*10^" ~ parts[2];
 }
Should be patrs[1], he? I had the same problem, but not for printing, but to do some math on them. Unfortunately math.h uses this internal (e.g. in trunc()) but doesn't give it to outside. I think it would be a good abstaction between the hardware-realated stuff and the interface - at the moment almost the same code is repeated three times over math.h always with the same version switches.
Aug 11 2014
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 11 August 2014 at 15:37:29 UTC, Dominikus Dittes 
Scherkl wrote:
 Should be patrs[1], he?
No, parts[1] contains a slice to the "e" separating the mantissa from the exponent.
Aug 11 2014
prev sibling parent reply Justin Whear <justin economicmodeling.com> writes:
On Mon, 11 Aug 2014 13:47:13 +0000, Nordlöw wrote:

 Is there a way to separately stringify/print the mantissa and exponent
 of a floating point?
 
 I want this in my pretty-printing module to produce something like
 
 1.2 \cdot 10^3
 
 instead of
 
 1.2e3
 
 I could of course always split on the e but that is kind of non-elegant,
 I believe.
If you're writing your own pretty-printer, you can extract those pieces using FloatRep[1] and print them however you like.
Aug 11 2014
next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 11 August 2014 at 15:30:30 UTC, Justin Whear wrote:

Great! Thx.
Aug 11 2014
prev sibling next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 11 August 2014 at 15:30:30 UTC, Justin Whear wrote:

I'm lacking a use case. See http://dlang.org/library/std/bitmanip/FloatRep.html Is unsafe *(cast(FloatRep*)&float_instance) the only way to use this?
Aug 11 2014
prev sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 11 August 2014 at 15:30:30 UTC, Justin Whear wrote:

Could someone briefly outline the algorithm that converts the fraction part of FloatRep into a string in base 10? My first guess is sum = 0; foreach (bit_index i, bit_value b; fraction) if (b == 1) sum += 2^^(-i); return to!string(sum); /Per
Aug 13 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 13 August 2014 at 07:51:30 UTC, Nordlöw wrote:

Can somebody shortly explain why import std.stdio, std.algorithm, std.range, std.stdio, std.bitmanip; void main(string args[]) { { float x = 1.23e10; auto y = *cast(FloatRep*)(&x); writeln(y.fraction, ", ", y.exponent, ", ", y.sign); } { double x = 1.23e10; auto y = *cast(DoubleRep*)(&x); writeln(y.fraction, ", ", y.exponent, ", ", y.sign); } } prints 3623111, 160, false 1945142772629504, 1056, false
Aug 13 2014
next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Wednesday, 13 August 2014 at 07:51:30 UTC, Nordlöw wrote:
 Could someone briefly outline the algorithm that converts the 
 fraction part of FloatRep into a string in base 10?
Walter Bright broke down the Floating point to explain how it works and why as i recall.. http://dlang.org/d-floating-point.html http://en.wikipedia.org/wiki/Floating_point http://en.wikipedia.org/wiki/Single-precision_floating-point_format As for the fraction part to floating point... You kinda have to think in reverse. If we have say a 4 bit floating point. So... 1000 +0.5 0100 +0.25 0010 +0.125 0001 +0.0625 With this in mind you might be better off using hex, but it depends on the application. On Wednesday, 13 August 2014 at 07:58:40 UTC, Nordlöw wrote:
 Can somebody shortly explain why it prints

 3623111, 160, false
 1945142772629504, 1056, false
Because they are raw int/uint types. But i'm sure that's not all that useful...
 x = 1.23e10;
so 12300000000 or 12,300,000,000 or 2DD231B00 they might make more sense in hex, but with the exponent really just shifting where the whole/fraction parts are separated. 160-128 = it's shifted to 32/33 bits as it's starting point. and the 1056-1024 at the 32/33 bit starting point. Same place. The raw values they hold in hex are: 3748c7 & 0000d8000000 Let's back up then. there is 23 bits of useful data we can use, and 34 bits present. So let's take our number and convert it to hex 2DD231B00 and lower that until it fits in 23 bits. Or shift it about 11 to the right.. And doing this I don't get very good results to feel like I'm helping much... I guess refer to the wiki on floating point is probably the best you can do... Although... I do recall seeing and having a hold of a formula for manually printing a floating point when I was looking at raw data before.. That formula was (don't ask where from, I don't remember.. might be on the wiki. This is from an AHK script): HexToFloat(d) { Return (1-2*(d>>31)) * (2**((d>>23 & 255)-127)) * (1+(d & 8388607)/8388608) ; 2**23 }
Aug 13 2014
prev sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 13 August 2014 at 07:58:40 UTC, Nordlöw wrote:
     {
         float x = 1.23e10;
         auto y = *cast(FloatRep*)(&x);
         writeln(y.fraction, ", ",
                 y.exponent, ", ",
                 y.sign);
     }

     {
         double x = 1.23e10;
         auto y = *cast(DoubleRep*)(&x);
         writeln(y.fraction, ", ",
                 y.exponent, ", ",
                 y.sign);
     }
 }
It would be nice to turn these into either - properties or at least - template overloads if possible as pointer casting unsafe and error-prone.
Aug 13 2014