我正在为LitJson做一个导入器,从int型和double型中导入浮点值,如果启用了溢出检查,我想在JsonException中包装一个潜在的溢出异常,并提供有关失败的更多信息。
现在我的代码看起来是这样的,我不知道我是否需要/可以检查上下文是否被检查:
private static float DoubleFloatImporter(double value) {
try
{
return (float)value;
}
catch (Exception ex)
{
throw new JsonException("Value is not a valid Single", ex);
}
}
您可能会想到checked
和unchecked
上下文,但这些与您的示例无关,从double
到float
的显式转换(强制转换)(即从双精度二进制浮点数到单精度)。
一个有限的double
值可以四舍五入到一个无限的float
值(float.PositiveInfinity
或float.NegativeInfinity
)。
例如DoubleFloatImporter(1.23e123)
。作为双精度类型,输入的1.23e123
将被表示为有限值,但当转换为float
时,最接近的可表示值将被解释为+∞。
编辑:正如我在评论中所说的,像这样:
private static float DoubleFloatImporter(double value) {
var converted = (float)value;
if (!float.IsFinite(converted))
throw new JsonException("Converted value would become infinite or not a number");
return converted;
}
可以满足你的需要。
这样怎么样:
static float DoubleFloatImporter(double value)
{
if (double.IsPositiveInfinity(value))
{
return float.PositiveInfinity;
}
if (double.IsNegativeInfinity(value))
{
return float.NegativeInfinity;
}
if (value > Single.MaxValue || value < Single.MinValue)
{
throw new OverflowException($"'{value}' doesn't fit");
}
return (float)value; //Single.CreateChecked(value);
}
一些例子:
using System.Runtime.CompilerServices;
Convert(1.0);
Convert(double.MaxValue);
Convert(double.PositiveInfinity);
Convert(double.NegativeInfinity);
Convert((double)float.MaxValue + 100);
Convert((double)float.MaxValue * 2);
Convert(double.NaN);
static void Convert(double v, [CallerArgumentExpression("v")] string arg1Exp = "?")
{
try
{
var f = DoubleFloatImporter(v);
Console.WriteLine($"{arg1Exp} -> {f}");
}
catch (Exception ex)
{
Console.WriteLine($"{arg1Exp} -> {ex.Message}");
}
}
输出:1.0 -> 1
double.MaxValue -> '1.7976931348623157E+308' doesn't fit
double.PositiveInfinity -> ∞
double.NegativeInfinity -> -∞
(double)float.MaxValue + 100 -> 3.4028235E+38
(double)float.MaxValue * 2 -> '6.805646932770577E+38' doesn't fit
double.NaN -> NaN