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 exceeds_expectations; 9 import std.math : isNaN; 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 expect(parseTomlFloat("3.14159")).toApproximatelyEqual(3.14159); 32 } 33 34 @("Fractional — With +") 35 unittest 36 { 37 expect(parseTomlFloat("+1.0")).toApproximatelyEqual(1.0); 38 } 39 40 @("Fractional — Negative") 41 unittest 42 { 43 expect(parseTomlFloat("-1.0")).toApproximatelyEqual(-1.0); 44 } 45 46 @("Exponential — Basic") 47 unittest 48 { 49 expect(parseTomlFloat("2e7")).toApproximatelyEqual(20_000_000.0); 50 } 51 52 @("Exponential — With +") 53 unittest 54 { 55 expect(parseTomlFloat("3e+05")).toApproximatelyEqual(300_000.0); 56 } 57 58 @("Exponential — Negative base/exponent/both") 59 unittest 60 { 61 expect(parseTomlFloat("-2e7")).toApproximatelyEqual(-20_000_000.0); 62 expect(parseTomlFloat("2e-7")).toApproximatelyEqual(0.0_000_002); 63 expect(parseTomlFloat("-2e-7")).toApproximatelyEqual(-0.0_000_002); 64 } 65 66 @("Fraxponential") 67 unittest 68 { 69 expect(parseTomlFloat("-3.14159e-03")).toApproximatelyEqual(-0.003_141_59); 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 expect(parseTomlFloat("inf")).toEqual(real.infinity); 84 expect(parseTomlFloat("+inf")).toEqual(real.infinity); 85 expect(parseTomlFloat("-inf")).toEqual(-real.infinity); 86 } 87 88 @("Underscores") 89 unittest 90 { 91 expect(parseTomlFloat("-3.1_41_59e-0_3")).toApproximatelyEqual(-0.003_141_59); 92 }