www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - to!string(double) at compile time

reply Bobby Bingham <uhmmmm gmail.com> writes:
I'm just getting started with D, and was playing around with string
mixins.  I've hit a snag, and have reduced it to a minimal test case:

    import std.conv;

    string test()
    {
        return to!string(0.0);
    }

    immutable auto testvar = mixin(test());

This gives this result when compiling:

/usr/include/phobos2/std/format.d(1479): Error: snprintf cannot be interpreted
at compile time, because it has no available source code
/usr/include/phobos2/std/conv.d(99):        called from here:
formatValue(w,src,f)
/usr/include/phobos2/std/conv.d(824):        called from here: toStr(value)
/usr/include/phobos2/std/conv.d(268):        called from here: toImpl(_param_0)
test.d(6):        called from here: to(0)
test.d(9):        called from here: test()
test.d(9): Error: argument to mixin must be a string, not (test())

I guess converting a double to a string can't be done at compile time
because it requires calling the C snprintf function?  It compiles fine
if I replace the 0.0 with an int literal.  Is there any way around
this limitation?
Aug 20 2012
next sibling parent "cal" <callumenator gmail.com> writes:
On Tuesday, 21 August 2012 at 04:43:09 UTC, Bobby Bingham wrote:
 I'm just getting started with D, and was playing around with 
 string
 mixins.  I've hit a snag, and have reduced it to a minimal test 
 case:

     import std.conv;

     string test()
     {
         return to!string(0.0);
     }

     immutable auto testvar = mixin(test());

 This gives this result when compiling:

 /usr/include/phobos2/std/format.d(1479): Error: snprintf cannot 
 be interpreted at compile time, because it has no available 
 source code
 /usr/include/phobos2/std/conv.d(99):        called from here: 
 formatValue(w,src,f)
 /usr/include/phobos2/std/conv.d(824):        called from here: 
 toStr(value)
 /usr/include/phobos2/std/conv.d(268):        called from here: 
 toImpl(_param_0)
 test.d(6):        called from here: to(0)
 test.d(9):        called from here: test()
 test.d(9): Error: argument to mixin must be a string, not 
 (test())

 I guess converting a double to a string can't be done at 
 compile time
 because it requires calling the C snprintf function?  It 
 compiles fine
 if I replace the 0.0 with an int literal.  Is there any way 
 around
 this limitation?
I have had to work around this also. One way is to first multiply your float by a large factor (say 10000 depending on what precision you want) and then adding a decimal point back in to the string. Kinda hacky, but... Here is an example: int fx = cast(int) (cos(angle)*1000000.); string fsx = fx.to!string; string xprefix; if (fsx[0] == '-') { xprefix = "-"; fsx = fsx[1..$]; } if (fsx.length == 7) sx = xprefix ~ fsx[0] ~ "." ~ fsx[1..$]; else sx = xprefix ~ "0." ~ fsx; sx is then the string you want to mixin.
Aug 20 2012
prev sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Aug 21, 2012 at 6:43 AM, Bobby Bingham <uhmmmm gmail.com> wrote:
 I'm just getting started with D, and was playing around with string
 mixins.  I've hit a snag, and have reduced it to a minimal test case:

     import std.conv;

     string test()
     {
         return to!string(0.0);
     }

     immutable auto testvar = mixin(test());
 I guess converting a double to a string can't be done at compile time
 because it requires calling the C snprintf function?  It compiles fine
 if I replace the 0.0 with an int literal.  Is there any way around
 this limitation?
A possibility is to use a function template, passing the double as a template argument: string test(double d)() // d is a template argument { return d.stringof; } enum testvar = mixin(test!(3.14)); void main() { pragma(msg, testvar); }
Aug 23 2012
parent timothee cour <thelastmammoth gmail.com> writes:
On Thursday, 23 August 2012 at 13:56:05 UTC, Philippe Sigaud 
wrote:
 On Tue, Aug 21, 2012 at 6:43 AM, Bobby Bingham 
 <uhmmmm gmail.com> wrote:
[...]
 [...]
A possibility is to use a function template, passing the double as a template argument: string test(double d)() // d is a template argument { return d.stringof; } enum testvar = mixin(test!(3.14)); void main() { pragma(msg, testvar); }
https://issues.dlang.org/show_bug.cgi?id=15497
Jan 01 2016