digitalmars.D.learn - wth!! ctfe cannot format floating point at compile time?
- Johnson Jones (6/6) Aug 13 2017 Error: uncaught CTFE exception std.format.FormatException("Cannot
- Adam D. Ruppe (16/19) Aug 13 2017 It uses a C function to do the conversion, which is not available
- Johnson (27/46) Aug 13 2017 I don't believe that! Just run dmd on it like ctfe does. Maybe
- Steven Schveighoffer (9/30) Aug 14 2017 Another reasonable idea is to have the compiler call the function for
- Adam D. Ruppe (6/8) Aug 14 2017 Yeah, I was thinking that too. Heck, the compiler prolly uses it
- HypperParrow (10/17) Aug 13 2017 There is this trick as workaround:
- Johnson (3/21) Aug 13 2017 Thanks! You'd think that to would do this internally
- Stefan Koch (3/10) Aug 14 2017 It only works on literals.
Error: uncaught CTFE exception std.format.FormatException("Cannot format floating point types at compile-time") called from here: to(0.75) pretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?
Aug 13 2017
On Monday, 14 August 2017 at 01:52:16 UTC, Johnson Jones wrote:pretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?It uses a C function to do the conversion, which is not available at compile time since CTFE can't run extern functions. And it is a LOT harder to do than you might think which is why it still uses the C function - implementing one in D is legit pretty complex. When I first saw this too, I figured it must be simple to slap something together, even if it is horribly inefficient and doesn't work everywhere... and I ended up giving up after spending a few hours on it too. If you search the web, you get academic papers describing it, eeek. Of course, it might be reasonable to port one of the C implementations directly... but even that is a fairly big job (and you might as well just call the C function itself for all but CTFE cases) - the GNU one is 1,300 lines, for example. And that has an incompatible license with the rest of druntime!
Aug 13 2017
On Monday, 14 August 2017 at 03:44:27 UTC, Adam D. Ruppe wrote:On Monday, 14 August 2017 at 01:52:16 UTC, Johnson Jones wrote:I don't believe that! Just run dmd on it like ctfe does. Maybe the problem is that to should be a bit more intelligent and if it is ran at ctfe should try something else. I don't see why it would be all that difficult maybe for complex floating point numbers it is but for most ordinary numbers used as most literals(e.g., terminating decimals), it is very very easy to convert. It is not much more difficult than storing it as a string. After all 0.43425 is actually a string that will be converted to fp. I realize there are accuracy issues but I seriously think there should be something suitable rather than crapping out ;/ e.g., 0.43425 = 43425/100000. Remember, we are converting a literal string represented floating point value to a string. It should be a direct conversion. Basically a copy and paste. (at run time, it is different, obviously since the value is actually a fp, but at compile time it is simply a string. There is this trick as workaround: As HypperParrow says, it's easy as pi: ``` auto valueToString(alias v)(){return v.stringof;} enum a = valueToString!(0.75); static assert(a == "0.75"); ``` to!string(float) should detect that and just do it. No need to try to do anything complex.pretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?It uses a C function to do the conversion, which is not available at compile time since CTFE can't run extern functions. And it is a LOT harder to do than you might think which is why it still uses the C function - implementing one in D is legit pretty complex. When I first saw this too, I figured it must be simple to slap something together, even if it is horribly inefficient and doesn't work everywhere... and I ended up giving up after spending a few hours on it too. If you search the web, you get academic papers describing it, eeek. Of course, it might be reasonable to port one of the C implementations directly... but even that is a fairly big job (and you might as well just call the C function itself for all but CTFE cases) - the GNU one is 1,300 lines, for example. And that has an incompatible license with the rest of druntime!
Aug 13 2017
On 8/13/17 11:44 PM, Adam D. Ruppe wrote:On Monday, 14 August 2017 at 01:52:16 UTC, Johnson Jones wrote:Another reasonable idea is to have the compiler call the function for you. Since the compiler only ever exists on platforms with libc available, the libc function is available to the compiler too. having some special intrinsic to format floating points wouldn't be out of the question. It is quite limiting to have floating point string conversions not available. -Stevepretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?It uses a C function to do the conversion, which is not available at compile time since CTFE can't run extern functions. And it is a LOT harder to do than you might think which is why it still uses the C function - implementing one in D is legit pretty complex. When I first saw this too, I figured it must be simple to slap something together, even if it is horribly inefficient and doesn't work everywhere... and I ended up giving up after spending a few hours on it too. If you search the web, you get academic papers describing it, eeek. Of course, it might be reasonable to port one of the C implementations directly... but even that is a fairly big job (and you might as well just call the C function itself for all but CTFE cases) - the GNU one is 1,300 lines, for example. And that has an incompatible license with the rest of druntime!
Aug 14 2017
On Monday, 14 August 2017 at 13:11:20 UTC, Steven Schveighoffer wrote:Another reasonable idea is to have the compiler call the function for you.Yeah, I was thinking that too. Heck, the compiler prolly uses it for reading source and writing errors. Perhaps just special case hack the function it uses in the ctfe engine.
Aug 14 2017
On Monday, 14 August 2017 at 01:52:16 UTC, Johnson Jones wrote:Error: uncaught CTFE exception std.format.FormatException("Cannot format floating point types at compile-time") called from here: to(0.75) pretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?There is this trick as workaround: ``` auto valueToString(alias v)(){return v.stringof;} enum a = valueToString!(0.75); static assert(a == "0.75"); ``` The problem with to() and format() is that is requires external library calls that are not available at compile-time, just like when you try to use malloc() at CT.
Aug 13 2017
On Monday, 14 August 2017 at 03:52:40 UTC, HypperParrow wrote:On Monday, 14 August 2017 at 01:52:16 UTC, Johnson Jones wrote:Thanks! You'd think that to would do this internally automatically ;/Error: uncaught CTFE exception std.format.FormatException("Cannot format floating point types at compile-time") called from here: to(0.75) pretty simply, trying to convert a floating point to a string in a ctfe function and it thinks that it is too complex to do in a ctfe, really?There is this trick as workaround: ``` auto valueToString(alias v)(){return v.stringof;} enum a = valueToString!(0.75); static assert(a == "0.75"); ``` The problem with to() and format() is that is requires external library calls that are not available at compile-time, just like when you try to use malloc() at CT.
Aug 13 2017
On Monday, 14 August 2017 at 04:29:17 UTC, Johnson wrote:It only works on literals. valueToString!(a) will give you a;``` auto valueToString(alias v)(){return v.stringof;} enum a = valueToString!(0.75); static assert(a == "0.75"); ```Thanks! You'd think that to would do this internally automatically ;/
Aug 14 2017