1 module toml_foolery.decode.types.floating_point; 2 3 import std.algorithm : filter; 4 import std.conv : to; 5 6 version (unittest) 7 { 8 import std.math : isNaN; 9 import dshould; 10 } 11 12 13 package(toml_foolery.decode) real parseTomlFloat(string value) 14 { 15 if (value[$-3 .. $] == "inf") 16 { 17 if (value[0] == '-') 18 { 19 return -real.infinity; 20 } 21 22 return real.infinity; 23 } 24 25 return value.filter!(e => e != '_').to!real; 26 } 27 28 @("Fractional — Basic") 29 unittest 30 { 31 parseTomlFloat("3.14159").should.equal.approximately(3.14159, error = 1.0e-05); 32 } 33 34 @("Fractional — With +") 35 unittest 36 { 37 parseTomlFloat("+1.0").should.equal.approximately(1.0, error = 1.0e-05); 38 } 39 40 @("Fractional — Negative") 41 unittest 42 { 43 parseTomlFloat("-1.0").should.equal.approximately(-1.0, error = 1.0e-05); 44 } 45 46 @("Exponential — Basic") 47 unittest 48 { 49 parseTomlFloat("2e7").should.equal.approximately(20_000_000.0, error = 1.0e-05); 50 } 51 52 @("Exponential — With +") 53 unittest 54 { 55 parseTomlFloat("3e+05").should.equal.approximately(300_000.0, error = 1.0e-05); 56 } 57 58 @("Exponential — Negative base/exponent/both") 59 unittest 60 { 61 parseTomlFloat("-2e7").should.equal.approximately(-20_000_000.0, error = 1.0e-05); 62 parseTomlFloat("2e-7").should.equal.approximately(0.0_000_002, error = 1.0e-05); 63 parseTomlFloat("-2e-7").should.equal.approximately(-0.0_000_002, error = 1.0e-05); 64 } 65 66 @("Fraxponential") 67 unittest 68 { 69 parseTomlFloat("-3.14159e-03").should.equal.approximately(-0.003_141_59, error = 1.0e-05); 70 } 71 72 @("NaN") 73 unittest 74 { 75 assert(parseTomlFloat("nan").isNaN, "Expected NaN, received: " ~ parseTomlFloat("nan").to!string); 76 assert(parseTomlFloat("+nan").isNaN, "Expected NaN, received: " ~ parseTomlFloat("+nan").to!string); 77 assert(parseTomlFloat("-nan").isNaN, "Expected NaN, received: " ~ parseTomlFloat("-nan").to!string); 78 } 79 80 @("Infinity") 81 unittest 82 { 83 parseTomlFloat("inf").should.equal(real.infinity); 84 parseTomlFloat("+inf").should.equal(real.infinity); 85 parseTomlFloat("-inf").should.equal(-real.infinity); 86 } 87 88 @("Underscores") 89 unittest 90 { 91 parseTomlFloat("-3.1_41_59e-0_3").should.equal.approximately(-0.003_141_59, error = 1.0e-05); 92 }