digitalmars.D.learn - Separate Printing Mantissa and Exponent of a Floating Point
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (8/8) Aug 11 2014 Is there a way to separately stringify/print the mantissa and
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (12/12) Aug 11 2014 Here's my current try:
- Dominikus Dittes Scherkl (10/22) Aug 11 2014 Should be patrs[1], he?
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (4/5) Aug 11 2014 No, parts[1] contains a slice to the "e" separating the mantissa
- Justin Whear (4/17) Aug 11 2014 If you're writing your own pretty-printer, you can extract those pieces
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (2/3) Aug 11 2014 Great! Thx.
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (6/7) Aug 11 2014 I'm lacking a use case. See
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (10/11) Aug 13 2014 Could someone briefly outline the algorithm that converts the
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (24/25) Aug 13 2014 Can somebody shortly explain why
- Era Scarecrow (40/46) Aug 13 2014 Walter Bright broke down the Floating point to explain how it
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (5/20) Aug 13 2014 It would be nice to turn these into either
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
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
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
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
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
On Monday, 11 August 2014 at 15:30:30 UTC, Justin Whear wrote:Great! Thx.
Aug 11 2014
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
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
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
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, falseBecause 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
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