Add custom floats formatting to prevent scientific notation
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
|
||||
@@ -20,8 +19,8 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp(value, _min, _max);
|
||||
if (Math.Abs(_value - value) > Mathf.Epsilon)
|
||||
value = Mathd.Clamp(value, _min, _max);
|
||||
if (Math.Abs(_value - value) > Mathd.Epsilon)
|
||||
{
|
||||
// Set value
|
||||
_value = value;
|
||||
@@ -39,7 +38,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _min;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_min, value))
|
||||
if (!Mathd.NearEqual(_min, value))
|
||||
{
|
||||
if (value > _max)
|
||||
throw new ArgumentException();
|
||||
@@ -56,7 +55,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _max;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_max, value))
|
||||
if (!Mathd.NearEqual(_max, value))
|
||||
{
|
||||
if (value < _min)
|
||||
throw new ArgumentException();
|
||||
@@ -78,7 +77,7 @@ namespace FlaxEditor.GUI.Input
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="slideSpeed">The slide speed.</param>
|
||||
public DoubleValueBox(double value, float x = 0, float y = 0, float width = 120, double min = double.MinValue, double max = double.MaxValue, float slideSpeed = 1)
|
||||
: base(Mathf.Clamp(value, min, max), x, y, width, min, max, slideSpeed)
|
||||
: base(Mathd.Clamp(value, min, max), x, y, width, min, max, slideSpeed)
|
||||
{
|
||||
UpdateText();
|
||||
}
|
||||
@@ -133,15 +132,7 @@ namespace FlaxEditor.GUI.Input
|
||||
/// <inheritdoc />
|
||||
protected sealed override void UpdateText()
|
||||
{
|
||||
string text;
|
||||
if (double.IsPositiveInfinity(_value) || _value == double.MaxValue)
|
||||
text = "Infinity";
|
||||
else if (double.IsNegativeInfinity(_value) || _value == double.MinValue)
|
||||
text = "-Infinity";
|
||||
else
|
||||
text = _value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
SetText(text);
|
||||
SetText(Utilities.Utils.FormatFloat(_value));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -140,15 +140,7 @@ namespace FlaxEditor.GUI.Input
|
||||
/// <inheritdoc />
|
||||
protected sealed override void UpdateText()
|
||||
{
|
||||
string text;
|
||||
if (float.IsPositiveInfinity(_value) || _value == float.MaxValue)
|
||||
text = "Infinity";
|
||||
else if (float.IsNegativeInfinity(_value) || _value == float.MinValue)
|
||||
text = "-Infinity";
|
||||
else
|
||||
text = _value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
SetText(text);
|
||||
SetText(Utilities.Utils.FormatFloat(_value));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -157,7 +149,7 @@ namespace FlaxEditor.GUI.Input
|
||||
try
|
||||
{
|
||||
var value = ShuntingYard.Parse(Text);
|
||||
Value = (float)Math.Round(value, 5);
|
||||
Value = (float)value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -272,8 +272,7 @@ namespace FlaxEditor.Utilities
|
||||
|
||||
// Operators go on stack, unless last operator on stack has higher precedence
|
||||
case TokenType.Operator:
|
||||
while (stack.Any() && stack.Peek().Type == TokenType.Operator &&
|
||||
CompareOperators(tok.Value, stack.Peek().Value))
|
||||
while (stack.Any() && stack.Peek().Type == TokenType.Operator && CompareOperators(tok.Value, stack.Peek().Value))
|
||||
{
|
||||
yield return stack.Pop();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
@@ -911,5 +912,98 @@ namespace FlaxEditor.Utilities
|
||||
}
|
||||
return StringUtils.GetPathWithoutExtension(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the floating point value (double precision) into the readable text representation.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The text representation.</returns>
|
||||
public static string FormatFloat(float value)
|
||||
{
|
||||
if (float.IsPositiveInfinity(value) || value == float.MaxValue)
|
||||
return "Infinity";
|
||||
if (float.IsNegativeInfinity(value) || value == float.MinValue)
|
||||
return "-Infinity";
|
||||
string str = value.ToString("r", CultureInfo.InvariantCulture);
|
||||
return FormatFloat(str, value < 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the floating point value (single precision) into the readable text representation.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The text representation.</returns>
|
||||
public static string FormatFloat(double value)
|
||||
{
|
||||
if (double.IsPositiveInfinity(value) || value == double.MaxValue)
|
||||
return "Infinity";
|
||||
if (double.IsNegativeInfinity(value) || value == double.MinValue)
|
||||
return "-Infinity";
|
||||
string str = value.ToString("r", CultureInfo.InvariantCulture);
|
||||
return FormatFloat(str, value < 0);
|
||||
}
|
||||
|
||||
internal static string FormatFloat(string str, bool isNegative)
|
||||
{
|
||||
// Reference: https://stackoverflow.com/questions/1546113/double-to-string-conversion-without-scientific-notation
|
||||
int x = str.IndexOf('E');
|
||||
if (x < 0)
|
||||
return str;
|
||||
int x1 = x + 1;
|
||||
string s, exp = str.Substring(x1, str.Length - x1);
|
||||
int e = int.Parse(exp);
|
||||
int numDecimals = 0;
|
||||
if (isNegative)
|
||||
{
|
||||
int len = x - 3;
|
||||
if (e >= 0)
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
s = str.Substring(0, 2) + str.Substring(3, len);
|
||||
numDecimals = len;
|
||||
}
|
||||
else
|
||||
s = str.Substring(0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
s = str.Substring(1, 1) + str.Substring(3, len);
|
||||
numDecimals = len;
|
||||
}
|
||||
else
|
||||
s = str.Substring(1, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = x - 2;
|
||||
if (len > 0)
|
||||
{
|
||||
s = str[0] + str.Substring(2, len);
|
||||
numDecimals = len;
|
||||
}
|
||||
else
|
||||
s = str[0].ToString();
|
||||
}
|
||||
if (e >= 0)
|
||||
{
|
||||
e -= numDecimals;
|
||||
string z = new string('0', e);
|
||||
s = s + z;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = -e - 1;
|
||||
string z = new string('0', e);
|
||||
if (isNegative)
|
||||
s = "-0." + z + s;
|
||||
else
|
||||
s = "0." + z + s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CircularBufferTests.cs" />
|
||||
<Compile Include="TestEditorUtils.cs" />
|
||||
<Compile Include="TestModulusOperator.cs" />
|
||||
<Compile Include="TestQuaternion.cs" />
|
||||
<Compile Include="TestSerialization.cs" />
|
||||
|
||||
60
Source/Tools/FlaxEngine.Tests/TestEditorUtils.cs
Normal file
60
Source/Tools/FlaxEngine.Tests/TestEditorUtils.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace FlaxEngine.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for <see cref="FlaxEditor.Utilities.Utils"/>.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestEditorUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Test floating point values formatting to readable text.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestFormatFloat()
|
||||
{
|
||||
Assert.AreEqual("0", FlaxEditor.Utilities.Utils.FormatFloat(0.0f));
|
||||
Assert.AreEqual("0", FlaxEditor.Utilities.Utils.FormatFloat(0.0d));
|
||||
Assert.AreEqual("0.1234", FlaxEditor.Utilities.Utils.FormatFloat(0.1234f));
|
||||
Assert.AreEqual("0.1234", FlaxEditor.Utilities.Utils.FormatFloat(0.1234d));
|
||||
Assert.AreEqual("1234", FlaxEditor.Utilities.Utils.FormatFloat(1234.0f));
|
||||
Assert.AreEqual("1234", FlaxEditor.Utilities.Utils.FormatFloat(1234.0d));
|
||||
Assert.AreEqual("1234.123", FlaxEditor.Utilities.Utils.FormatFloat(1234.123f));
|
||||
Assert.AreEqual("1234.1234", FlaxEditor.Utilities.Utils.FormatFloat(1234.1234d));
|
||||
|
||||
double[] values =
|
||||
{
|
||||
123450000000000000.0, 1.0 / 7, 10000000000.0 / 7, 100000000000000000.0 / 7, 0.001 / 7, 0.0001 / 7, 100000000000000000.0, 0.00000000001,
|
||||
1.23e-2, 1.234e-5, 1.2345E-10, 1.23456E-20, 5E-20, 1.23E+2, 1.234e5, 1.2345E10, -7.576E-05, 1.23456e20, 5e+20, 9.1093822E-31, 5.9736e24,
|
||||
double.Epsilon, Mathd.Epsilon, Mathf.Epsilon
|
||||
};
|
||||
foreach (int sign in new[] { 1, -1 })
|
||||
{
|
||||
foreach (double value in values)
|
||||
{
|
||||
double value1 = sign * value;
|
||||
string text = FlaxEditor.Utilities.Utils.FormatFloat(value1);
|
||||
Assert.IsFalse(text.Contains("e"));
|
||||
Assert.IsFalse(text.Contains("E"));
|
||||
double value2 = double.Parse(text);
|
||||
Assert.AreEqual(value2, value1);
|
||||
}
|
||||
}
|
||||
foreach (int sign in new[] { 1, -1 })
|
||||
{
|
||||
foreach (double value in values)
|
||||
{
|
||||
float value1 = (float)(sign * value);
|
||||
string text = FlaxEditor.Utilities.Utils.FormatFloat(value1);
|
||||
Assert.IsFalse(text.Contains("e"));
|
||||
Assert.IsFalse(text.Contains("E"));
|
||||
float value2 = float.Parse(text);
|
||||
Assert.AreEqual(value2, value1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user