对于需要精确到 0.00001 的翻译,十进制或双精度会更好吗?
我是一家机械厂的检验员。我有另一个检查员生成的 html 报告,其中有一些问题需要修复。这不是第一次:我需要比 PowerShell
和 RegEx
更好的东西。 (不要害怕网络战士,我知道我不应该将 RegEx
用于 html。我现在使用 HtmlAgilityPack
。)
我知道有很多类似的讨论在 SO 和一般互联网上。我没有找到任何如此具体的东西。我可以编写一些小型实验应用程序来测试其中的一些(并且我计划这样做),但是,在我实现所有这些之前,我想了解一下它在未来是否安全。尽管我不是一名程序员,但我对我们正在讨论的概念有很好的掌握;别担心在我头上说话。
经过一系列的转换,我是否可能会出现超过 0.0001 的错误? .00001 怎么样?
-如果报告的对齐方式关闭,我可能需要多次旋转和翻译它。
-我目前只实现了旋转和平移,但是我计划添加更多转换,这可能会增加操作的数量和复杂性。
-整数部分可以达到数千。
-我们的仪器通常经过 0.0001 级认证。适用科学测量的正常有效数字规则。
Decimal
和手动编写三角函数的开销是否会非常耗时(编辑:在运行时)?
- 一份报告通常有 100 到 100 分。每个点实际上是 2 个点:标称
(按照模型)和实际
(按照测量)。
-最容易测试,但我想在实现 Decimal 的数学函数之前知道。
附带问题:
我有一个点类 Point3D
,它包含 x
、y
和 z
。由于每个数据点都是其中的两个(Nominal
和 Actual
)。然后我有一个类 MeasuredPoint
,其中有两个 Point3D
实例。必须有一个比 MeasuredPoint
更好的名称,而且长度也不会令人烦恼。
哦,是的,这是 C#/.Net。谢谢,
I'm an inspector at a machine shop. I have an html report generated by another inspector that has some problems I need to fix. This isn't the first time: I need something better than PowerShell
and RegEx
. (Fear not internet warriors, I know I shouldn't use RegEx
for html. I'm using HtmlAgilityPack
now.)
I'm aware there are a lot of similar discussions on SO and on the internet in general. I didn't find anything quite this specific. I can write some small experiment apps to test some of this (and I plan to) but, I want to have some idea of if it will be future safe before I implement all of it. Even though I'm not a programmer by trade I have a good grasp of the concepts we're talking about; Don't worry about talking over my head.
Over a series of transformations is it likely I will have more than .0001 error? What about .00001?
-If a report's alignment is off, I may need to rotate and translate it multiple times.
-I've only implemented rotation and translation at this time but, I plan on adding more transformations that may increase the number and complexity of operations.
-The integer component can go into the thousands.
-Our instruments are certified to .0001 typically. Normal significant digit rules for scientific measurements apply.
Will the overhead of Decimal
and writing the trig functions manually be incredibly time consuming (edit: at runtime)?
-Typically a report has 100 to 100 points. Each point is actually 2 points: Nominal
(as modeled) and Actual
(as measured.)
-Easiest to test, but I want to know before implementing math functions for Decimal.
Side question:
I have a point class, Point3D
, that holds x
, y
and z
. Since each data point is two of these (the Nominal
and Actual
.) I then have a class, MeasuredPoint
, with two Point3D
instances. There has to be a better name than MeasuredPoint
that isn't annoyingly long.
Oh yeah, this is C#/.Net. Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不要用 Decimal 实现三角函数!标准库不提供它们是有原因的,那就是如果您正在执行三角函数,Decimal 不会提供任何额外的好处。
由于无论如何您都将以弧度为单位,因此您的值被定义为 PI 的倍数/比率,这在任何基本系统中都无法表示。强制表示以十为基数更有可能增加而不是减少错误。
如果精度(ulps 中的最小误差)对您的应用很重要,那么您必须阅读什么每个计算机科学家都应该了解浮点运算,作者:David Goldberg。那篇文章比我更好地解释了这一点。
然而,结果是,如果您所需的精度仅为小数点后 5 位,即使是 32 位浮点(IEEE-754 单精度)也足够了。 64 位双 IEEE-754 双精度将帮助您更精确地计算误差项,但 128 位以 10 为基数的浮点值只会破坏性能,并且几乎肯定不会提高精度你的结果一丁点。
Don't implement trig functions with Decimal! There's a reason why the standard library doesn't provide them, which is that if you're doing trig, Decimal doesn't provide any added benefit.
Since you're going to be working in radians anyway, your values are defined as multiples/ratios of PI, which isn't representable in any base system. Forcing the representation to base ten is more likely to increase than decrease error.
If precision (minimum error in ulps) is important for your application, then you must read What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg. That article does a much better job explaining than I would.
The upshot however is that if your desired precision is only 5 decimal places, even a 32-bit float (IEEE-754 single-precision) is going to be plenty. A 64-bit double IEEE-754 double-precision will help you be more precise with your error term, but a 128-bit base-10 floating-point value is just performance-killing overkill, and almost certainly won't improve the precision of your results one iota.
如果您需要在多个操作中保持准确性,那么您确实应该考虑使用 Decimal。虽然短时间保存数字可能没问题,但随着应用操作数量的增加,任何 IEEE754 支持的浮点格式都无法无限期地维持其值。
If you need accuracy to be maintained over multiple operations then you really ought to consider using Decimal. While it may be okay for holding numbers for a short time, no IEEE754-backed float format can sustain its value indefinitely as the number of operations applied increases.
尝试寻找能够满足您需求的图书馆。我在半心半意的搜索中偶然发现了 W3b.sine。我过去肯定遇到过其他人。
Try looking for a library that would handle your needs. I stumbled across W3b.sine in a half-hearted search. I've definitely encountered others in the past.
由于您正在讨论旋转和平移以及三角函数,因此可以安全地假设您正在讨论的值不是 0.0001 的精确倍数。
基于此假设:
使用小数,您在每一步之后基本上都会四舍五入到 0.0001(或您选择的精度),并且这些舍入误差将会累积。
双精度值通常会更准确:您将在内部存储所有可用的精度,并在显示结果时四舍五入到小数点后四位。
例如,作为旋转或变换的结果,您希望移动 1/3 (0.333....) 的距离。你想重复这个动作三遍。
如果将距离存储为具有四位小数的小数 (0.3333),则总和将为 0.9999,误差为 0.0001。
如果您存储为双精度数,则可以获得更高的精度,并且作为奖励,性能会更好。
实际上,小数通常仅用于财务计算,其中结果需要精确四舍五入到小数点后十位的固定位数。
Since you are talking about rotations as well as translations, as well as trigonometry functions, it seems safe to assume the values you are talking about are not exact multiples of 0.0001.
Based on this assumption:
With decimals, you will be essentially be rounding to 0.0001 (or your chosen precision) after each step, and these rounding errors will cumulate.
Double values would generally be more accurate: you would store internally with all available precision, and round to four decimals when displaying results.
For example, as the result of a rotation or transformation, you want to move by a distance of 1/3 (0.333....). And you want to repeat this movement three times.
If you store the distances as decimal with four decimal places (0.3333), the sum will be 0.9999, an error of 0.0001.
If you store as doubles, you can achieve much higher precision, and as a bonus performance will be better.
Really decimals are usually only used for financial calculations, where results are need to be exactly rounded to a fixed number of base ten decimal places.
浮点数和双精度数是快速近似值,就是这样。
除了
0.0
和1.0
之外,您甚至无法获得大多数常量的精确表示(<例如代码>0.1)。因此,如果您必须保证一定的精度,那么使用浮点运算不是一个选择。但如果目标是达到一定的精度,稍微调整一下,那么 double 就可以了。请注意重要性丧失。
Floats and Doubles are fast approximations, that's it.
Apart from
0.0
and1.0
, you won't even get exact representations for most constants (0.1
for instance). So if you have to guarantee a certain precision, using floating point arithmetic is not an option.But if the goal is to achieve a certain precision, give or take a bit, then double might do. Just watch out for Loss of significance.
坦率地说,我认为 FLOAT 在数据处理中是一个错误的转向。因为人们以十进制工作,并且输出总是转换为十进制,所以浮点只会导致持续的问题。当变量可以容纳大范围的值(例如从 1E-9 到 1E9 的范围)时,我曾经使用浮点型,否则使用在代码中管理的具有固定小数位数的整数。如今,有了 Java BigDecimal 类和其他语言中的类似功能,几乎没有理由使用浮点数。也许在您进行大量计算且性能成为问题的环境中,您会接受舍入问题。我想我至少有十年没有在程序中使用过浮点数了。
Frankly, I think FLOAT was a wrong turn in data processing. Because people work in decimal, and output is always translated into decimal, float just causes continual problems. I used to use float when a variable could hold a wide range of values, as in from 1E-9 to 1E9 kind of range, and use integers with a fixed number of decimal places managed in code otherwise. These days with the Java BigDecimal class and similar functionality in other languages, there's almost no reason to use float. Perhaps in an environment where you are doing a lot of calculations and performance is an issue, you'd accept the rounding problems. I don't think I've used a float in a program in at least ten years.