System.Double 在 WinRT 上输入 Windows.Foundation.Size.Width / .Height
System.Double type in Windows.Foundation.Size.Width / .Height on WinRT
我在 WinRT 上分配 double
类型的值时遇到问题。
以下代码:
Windows.Foundation.Size size = new Windows.Foundation.Size();
double v = 179.166660308838;
double v2 = v;
size.Width = v;
string t = $"v: {v}, v2: {v2}, size.Width: {size.Width}";
returnsv: 179.166660308838, v2: 179.166660308838, size.Width: 179.166656494141
。如您所见,v2
和 size.Width
的值不同。
我的问题是:
- 这是为什么?
- 如果我必须在 Windows.Foundation.Size 中存储一个值(例如在
MeasureOverride
/ArrangeOverride
中),如何使其按预期工作?
正如 Hans Passant 在评论中提到的那样 "The underlying storage type for Size's properties is float, not double. A float can only round-trip 6 significant digits, if you display more of them then you'll see random noise digits."
(Documentation)
你可以使用反射检查它:
var sizeFields = typeof(Windows.Foundation.Size).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Select(f => $"{f.Name} - {f.FieldType.Name}");
Debug.WriteLine(String.Join(", ", sizeFields));
在输出中你会看到_width - Single, _height - Single
如果反汇编 System.Runtime.WindowsRuntime.dll 你将在构造函数中看到以下代码:
public Size(double width, double height)
{
if (width < 0.0)
throw new ArgumentException("width");
if (height < 0.0)
throw new ArgumentException("height");
this._width = (float) width;
this._height = (float) height;
}
我在 WinRT 上分配 double
类型的值时遇到问题。
以下代码:
Windows.Foundation.Size size = new Windows.Foundation.Size();
double v = 179.166660308838;
double v2 = v;
size.Width = v;
string t = $"v: {v}, v2: {v2}, size.Width: {size.Width}";
returnsv: 179.166660308838, v2: 179.166660308838, size.Width: 179.166656494141
。如您所见,v2
和 size.Width
的值不同。
我的问题是:
- 这是为什么?
- 如果我必须在 Windows.Foundation.Size 中存储一个值(例如在
MeasureOverride
/ArrangeOverride
中),如何使其按预期工作?
正如 Hans Passant 在评论中提到的那样 "The underlying storage type for Size's properties is float, not double. A float can only round-trip 6 significant digits, if you display more of them then you'll see random noise digits." (Documentation)
你可以使用反射检查它:
var sizeFields = typeof(Windows.Foundation.Size).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Select(f => $"{f.Name} - {f.FieldType.Name}");
Debug.WriteLine(String.Join(", ", sizeFields));
在输出中你会看到_width - Single, _height - Single
如果反汇编 System.Runtime.WindowsRuntime.dll 你将在构造函数中看到以下代码:
public Size(double width, double height)
{
if (width < 0.0)
throw new ArgumentException("width");
if (height < 0.0)
throw new ArgumentException("height");
this._width = (float) width;
this._height = (float) height;
}