标签: precision

C 中的无限正弦生成

我正在开发一个项目,其中包含计算正弦波作为控制环路的输入。

\n

正弦波的频率为 280 Hz,控制循环每 30\xc2\xa0\xc2\xb5s 运行一次,并且针对 Arm Cortex-M7 的所有内容都是用 C 编写的。

\n

目前我们只是在做:

\n
double time;\nvoid control_loop() {\n    time += 30e-6;\n    double sine = sin(2 * M_PI * 280 * time);\n    ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

出现两个问题:

\n
    \n
  1. 跑久了time就会变大。突然之间,正弦函数的计算时间急剧增加(见图)。为什么是这样?这些功能通常是如何实现的呢?由于速度对我们来说是一个重要因素,有没有办法规避这个问题(没有明显的精度损失)?我们使用 math.h (Arm GCC) 中的 sin。\nsin 函数分析
  2. \n
  3. 我一般如何处理时间?当长时间运行时,变量time不可避免地会达到双精度的极限。即使使用计数器time = counter++ * 30e-6;也只能改善这一点,但并不能解决问题。由于我当然不是第一个想要长时间生成正弦波的人,因此必须有一些关于如何快速而精确地实现这一点的想法/论文/...。
  4. \n
\n

c precision performance time trigonometry

89
推荐指数
10
解决办法
1万
查看次数

为什么SQL中的199.96 - 0 = 200?

我有一些客户收到奇怪的账单.我能够找出核心问题:

SELECT 199.96 - (0.0 * FLOOR(CAST(1.0 AS DECIMAL(19, 4)) * CAST(199.96 AS DECIMAL(19, 4)))) -- 200 what the?
SELECT 199.96 - (0.0 * FLOOR(1.0 * CAST(199.96 AS DECIMAL(19, 4)))) -- 199.96
SELECT 199.96 - (0.0 * FLOOR(CAST(1.0 AS DECIMAL(19, 4)) * 199.96)) -- 199.96

SELECT 199.96 - (CAST(0.0 AS DECIMAL(19, 4)) * FLOOR(CAST(1.0 AS DECIMAL(19, 4)) * CAST(199.96 AS DECIMAL(19, 4)))) -- 199.96
SELECT 199.96 - (CAST(0.0 AS DECIMAL(19, 4)) * FLOOR(1.0 * CAST(199.96 AS DECIMAL(19, 4))))                         -- 199.96 …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server precision sqldatatypes sql-server-2016

83
推荐指数
2
解决办法
5941
查看次数

PHP - 浮点数精度

$a = '35';
$b = '-34.99';
echo ($a + $b);
Run Code Online (Sandbox Code Playgroud)

结果在0.009999999999998

怎么了?我想知道为什么我的程序会报告奇怪的结果.

为什么PHP没有返回预期的0.01?

php floating-point precision floating-accuracy

77
推荐指数
4
解决办法
4万
查看次数

75
推荐指数
4
解决办法
22万
查看次数

在MATLAB中,默认情况下变量是否真的是双精度?

这个问题产生于我在进一步调查这个问题后发现的一些奇怪的事情......

我总是将MATLAB变量理解为默认的双精度.所以,如果我要做一些事情,比如声明一个小数点后20位数的变量:

>> num = 2.71828182845904553488;
>> class(num)  % Display the variable type
ans =
double
Run Code Online (Sandbox Code Playgroud)

我希望忽略最后4位数,因为浮点相对精度大约为10 -16:

>> eps(num)
ans =
    4.440892098500626e-016
Run Code Online (Sandbox Code Playgroud)

如果我尝试在小数点后面显示超过16位的数字(使用fprintf或者sprintf),我得到的结果是:

>> fprintf('%0.20f\n', num)
2.71828182845904550000
>> sprintf('%0.20f', num)
ans =
2.71828182845904550000
Run Code Online (Sandbox Code Playgroud)

换句话说,数字17到20都是0.

但是,事情变得奇怪,当我传球num可变精度算术函数符号工具箱,告诉它表示使用的精度21个的位数:

>> vpa(num, 21)
ans =
2.71828182845904553488
Run Code Online (Sandbox Code Playgroud)

什么?!最后4位数字再次出现!当我输入的原始数字存储为双精度变量时,它们是否应该丢失num?既然num传递给它是一个双精度变量vpa,怎么vpa知道它们是什么?

我最好的猜测是,MATLAB内部表示的num精度高于双精度,因为我将它初始化为一个数字,其数字超过小数点,而不是双精度变量可以处理的数字.这真的是发生了什么,还是正在发生的事情?



奖励:如果你还没有上述的偏头痛,这里还有另外一个混乱的根源......

>> num = 2.71828182845904553488;  % Declare …
Run Code Online (Sandbox Code Playgroud)

variables floating-point precision matlab

72
推荐指数
1
解决办法
3万
查看次数

在16位,32位和64位IEEE-754系统中可以表示哪些数字?

我知道浮点数是如何表示的,但是还不够,我害怕.

一般问题是:

对于给定的精度(对于我的目的,基数10中的精确小数位数),可以为16位,32位和64位IEEE-754系统表示什么范围的数字?

具体来说,我只对16位和32位数字的范围感兴趣,精确到+/- 0.5(那些位置)或+/- 0.0005(千分位数).

floating-point precision numerical ieee-754

71
推荐指数
4
解决办法
7万
查看次数

为什么在MATLAB中24.0000不等于24.0000?

我正在编写一个程序,我需要删除存储在矩阵中的重复点.问题在于,当检查这些点是否在矩阵中时,MATLAB不能在矩阵中识别它们,尽管它们存在.

在以下代码中,intersections函数获取交集点:

[points(:,1), points(:,2)] = intersections(...
    obj.modifiedVGVertices(1,:), obj.modifiedVGVertices(2,:), ...
    [vertex1(1) vertex2(1)], [vertex1(2) vertex2(2)]);
Run Code Online (Sandbox Code Playgroud)

结果:

>> points
points =
   12.0000   15.0000
   33.0000   24.0000
   33.0000   24.0000

>> vertex1
vertex1 =
    12
    15

>> vertex2    
vertex2 =
    33
    24
Run Code Online (Sandbox Code Playgroud)

应从结果中消除两点(vertex1vertex2).它应该通过以下命令完成:

points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :);
points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);
Run Code Online (Sandbox Code Playgroud)

在这之后,我们有了这个意想不到的结果:

>> points
points =
   33.0000   24.0000
Run Code Online (Sandbox Code Playgroud)

结果应该是一个空矩阵.如你所见,第一对(或第二对)[33.0000 24.0000]已被淘汰,但不是第二对.

然后我检查了这两个表达式:

>> points(1) ~= vertex2(1)
ans …
Run Code Online (Sandbox Code Playgroud)

floating-point precision matlab

67
推荐指数
4
解决办法
2万
查看次数

PHP7.1 json_encode()Float问题

这不是一个问题,因为它更多的是意识到.我更新了一个json_encode()用于PHP7.1.1 的应用程序,我看到一个问题,浮动被更改为有时延伸出17位数.根据文档,serialize_precision在编码double值时,PHP 7.1.x开始使用而不是精度.我猜这导致了一个示例值

472.185

成为

472.18500000000006

在那个价值经历之后json_encode().自从我发现以来,我已经恢复到PHP 7.0.16并且我不再有问题了json_encode().我还尝试在恢复到PHP 7.0.16之前更新到PHP 7.1.2.

这个问题背后的原因确实源于PHP - 浮点数精度,但最终所有原因都是因为从精度到serialize_precision使用的变化json_encode().

如果有人知道这个问题的解决方案,我会非常乐意听取推理/修复.

摘自多维数组(之前):

[staticYaxisInfo] => Array
                    (
                        [17] => stdClass Object
                            (
                                [variable_id] => 17
                                [static] => 1
                                [min] => 0
                                [max] => 472.185
                                [locked_static] => 1
                            )

                    )
Run Code Online (Sandbox Code Playgroud)

经过json_encode()......之后

"staticYaxisInfo":
            {
                "17":
                {
                    "variable_id": "17",
                    "static": "1",
                    "min": 0,
                    "max": 472.18500000000006,
                    "locked_static": "1"
                }
            },
Run Code Online (Sandbox Code Playgroud)

php precision json php-7.1

67
推荐指数
4
解决办法
2万
查看次数

调整小数精度,.net

C#中的这些行

decimal a = 2m;
decimal b = 2.0m;
decimal c = 2.00000000m;
decimal d = 2.000000000000000000000000000m;

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
Run Code Online (Sandbox Code Playgroud)

生成此输出:

2
2.0
2.00000000
2.000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

所以我可以看到从文字中创建一个十进制变量允许我控制精度.

  • 我可以在不使用文字的情况下调整十进制变量的精度吗?
  • 我如何从一个?创建b?如何从c创建b?

.net precision decimal

63
推荐指数
5
解决办法
6万
查看次数

为什么C中的double会比C++打印更少的十进制数字?

我在C中有这个代码,我已经宣布0.1为double.

#include <stdio.h> 
int main() {
    double a = 0.1;

    printf("a is %0.56f\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这就是它的印刷品, a is 0.10000000000000001000000000000000000000000000000000000000

C++中的代码相同,

#include <iostream>
using namespace std;
int main() {
    double a = 0.1;

    printf("a is %0.56f\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这就是它的印刷品, a is 0.1000000000000000055511151231257827021181583404541015625

有什么不同?当我读到两个都被分配8个字节?C++如何在小数位上打印更多数字?

另外,它怎么能到小数点55位?IEEE 754浮点只有52位的小数,我们可以得到15位十进制数的精度.它以二进制形式存储.为什么它的十进制解释存储更多?

c c++ floating-point precision numbers

63
推荐指数
2
解决办法
4441
查看次数