digitalmars.D - Compile time float binary representation
- Jeremie Pelletier (5/5) Jul 31 2009 Is there a way to convert a float (or double/real) to an integral number...
- Andrei Alexandrescu (14/22) Jul 31 2009 I got this to work, would it be applicable to your need?
- Jeremie Pelletier (19/45) Jul 31 2009 Good suggestion, however it doesnt work the way I need it:
- Jeremie Pelletier (11/62) Jul 31 2009 After some toying around, I managed to get some results:
- Andrei Alexandrescu (7/72) Jul 31 2009 Yah, I crashed it a couple of times with similar code now too. Could you...
- Jeremie Pelletier (3/79) Jul 31 2009 Thanks again for the quick reply Andrei, however, as useful as the Custo...
- Walter Bright (2/10) Jul 31 2009 There's currently no way to do that.
- Don (6/14) Aug 01 2009 There's a super-hacky way: pass the real as a template value parameter,
Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?
Jul 31 2009
Jeremie Pelletier wrote:Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?I got this to work, would it be applicable to your need? void main(string[] args) { union A { double x; int y; } enum A a = A(0.3); writeln(a.x); writeln(a.y); } Andrei
Jul 31 2009
Andrei Alexandrescu Wrote:Jeremie Pelletier wrote:Good suggestion, however it doesnt work the way I need it: --- template FloatParts(real R) { union A { real theReal; struct { ushort hi; ulong lo; } } A a = cast(A)R; // Error: cannot cast real to immutable(A) enum A a = A(R); // members cannot be used at runtime } --- I need to gather .sign, .exp and .mantissa among others (possibly a .radix too) and use them at compile time (generic metaprogramming, or else i would just fallback to runtime). Unless there are arithmetic methods to get these, I dont see how it can be done without changes in the compiler first. To Walter: is this something possible for DMD2.32?Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?I got this to work, would it be applicable to your need? void main(string[] args) { union A { double x; int y; } enum A a = A(0.3); writeln(a.x); writeln(a.y); } Andrei
Jul 31 2009
Jeremie Pelletier Wrote:Andrei Alexandrescu Wrote:After some toying around, I managed to get some results: --- import std.metastrings; immutable union A { double x; int y; } pragma(msg, ToString!(A(5.2).y)); --- but it crashed dmd (2.031) instead of printing 3435973837 to stdout.Jeremie Pelletier wrote:Good suggestion, however it doesnt work the way I need it: --- template FloatParts(real R) { union A { real theReal; struct { ushort hi; ulong lo; } } A a = cast(A)R; // Error: cannot cast real to immutable(A) enum A a = A(R); // members cannot be used at runtime } --- I need to gather .sign, .exp and .mantissa among others (possibly a .radix too) and use them at compile time (generic metaprogramming, or else i would just fallback to runtime). Unless there are arithmetic methods to get these, I dont see how it can be done without changes in the compiler first. To Walter: is this something possible for DMD2.32?Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?I got this to work, would it be applicable to your need? void main(string[] args) { union A { double x; int y; } enum A a = A(0.3); writeln(a.x); writeln(a.y); } Andrei
Jul 31 2009
Jeremie Pelletier wrote:Jeremie Pelletier Wrote:Yah, I crashed it a couple of times with similar code now too. Could you please do the bugzilla honors. (Also you may want to check std.numeric.CustomFloat. It doesn't help with this particular problem, but it allows defining floating point types with specific mantissa and exponent sizes.) AndreiAndrei Alexandrescu Wrote:After some toying around, I managed to get some results: --- import std.metastrings; immutable union A { double x; int y; } pragma(msg, ToString!(A(5.2).y)); --- but it crashed dmd (2.031) instead of printing 3435973837 to stdout.Jeremie Pelletier wrote:Good suggestion, however it doesnt work the way I need it: --- template FloatParts(real R) { union A { real theReal; struct { ushort hi; ulong lo; } } A a = cast(A)R; // Error: cannot cast real to immutable(A) enum A a = A(R); // members cannot be used at runtime } --- I need to gather .sign, .exp and .mantissa among others (possibly a .radix too) and use them at compile time (generic metaprogramming, or else i would just fallback to runtime). Unless there are arithmetic methods to get these, I dont see how it can be done without changes in the compiler first. To Walter: is this something possible for DMD2.32?Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?I got this to work, would it be applicable to your need? void main(string[] args) { union A { double x; int y; } enum A a = A(0.3); writeln(a.x); writeln(a.y); } Andrei
Jul 31 2009
Andrei Alexandrescu Wrote:Jeremie Pelletier wrote:Thanks again for the quick reply Andrei, however, as useful as the CustomFloat template may be, I need a reverse algorithm usable entirely at compile time. If you know a way to extract this information without resorting to bitwise logic, please let me know, for the moment I'm adding a static assert(0) to my template until dmd supports compile time binary casts. Also I created http://d.puremagic.com/issues/show_bug.cgi?id=3220.Jeremie Pelletier Wrote:Yah, I crashed it a couple of times with similar code now too. Could you please do the bugzilla honors. (Also you may want to check std.numeric.CustomFloat. It doesn't help with this particular problem, but it allows defining floating point types with specific mantissa and exponent sizes.) AndreiAndrei Alexandrescu Wrote:After some toying around, I managed to get some results: --- import std.metastrings; immutable union A { double x; int y; } pragma(msg, ToString!(A(5.2).y)); --- but it crashed dmd (2.031) instead of printing 3435973837 to stdout.Jeremie Pelletier wrote:Good suggestion, however it doesnt work the way I need it: --- template FloatParts(real R) { union A { real theReal; struct { ushort hi; ulong lo; } } A a = cast(A)R; // Error: cannot cast real to immutable(A) enum A a = A(R); // members cannot be used at runtime } --- I need to gather .sign, .exp and .mantissa among others (possibly a .radix too) and use them at compile time (generic metaprogramming, or else i would just fallback to runtime). Unless there are arithmetic methods to get these, I dont see how it can be done without changes in the compiler first. To Walter: is this something possible for DMD2.32?Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?I got this to work, would it be applicable to your need? void main(string[] args) { union A { double x; int y; } enum A a = A(0.3); writeln(a.x); writeln(a.y); } Andrei
Jul 31 2009
Jeremie Pelletier wrote:Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get. The usual *cast(uint*)&value wont work either at compile time. Any suggestions?There's currently no way to do that.
Jul 31 2009
Jeremie Pelletier wrote:Is there a way to convert a float (or double/real) to an integral number without changing its binary representation at compile time? I need to extract the sign, exponent and mantissa yet I cant use bit shifting. "Error: 'R' is not of integral type, it is a real" is the error I get.There's a super-hacky way: pass the real as a template value parameter, and parse the .mangleof it! Not recommended, but it does work. The other way is to do it with CTFE, subtracting powers of 2 until the residual is < 1. Not great either.The usual *cast(uint*)&value wont work either at compile time. Any suggestions?
Aug 01 2009