小编Dar*_*zka的帖子

电子表格计算(至少)C double的准确性

当我注意到Libre Office电子表格显示远远低于2 ^ 53的数字的错误值时,我正在做一些计算以计划我的主筛的改进实现,这是FoxPro中的精确整数计算的限制以及众多其他内部使用C double(即IEEE 754双)的语言.

一些快速检查显示数字低至2 ^ 50的错误结果.更糟糕的是,这个片状软件没有发出任何超出其操作限制的警告,并且显示的值只是近似值(即使手动输入了正确的值).我猜他们认为什么对于像Excel这样的POS来说足够好然后必须对他们足够好(但是他们应该把它命名为'Guesstimate'而不是'Calc'然后).

无论如何,是否有可能将电子表格放入某种精确模式,至少给出a的精度double,和/或当某些计算超出其数值能力时,它会显示某种警告?

或者是否有一些其他电子表格适用于甚至电话和烤面包机由64位芯片供电的时代的程序员?

背景:在这种特殊情况下,需要精确度,因为通过比较某些结果列和众所周知的数字列表(如最多2 ^ k的素数,可从OEIS获得)或数字来验证公式的精确性源自检测代码.我们的想法是通过检查它们的可行范围来获得正确的公式 - 最多在2 ^ 32和2 ^ 40之间 - 然后使用这些公式来研究范围最大为2 ^ 64的行为(这是不可能的通过详尽的测试获得完整的图片.

PS:我发现在"电子表格的数字准确性"(pdf)中已经对该问题进行了广泛的分析.似乎gnumeric比其他人更好一点,但更多的是盲人中的独眼人而不是真正的通过集合; 此外,它不适用于Windows,因此需要在我正在开发的平台上启动Linux VM以及...

UPDATE /替代方法

最多2 ^ 49没有问题,因此可以正常工作.这足以准确了解事物.在最终表格中,大数字和高精度结果(在其他地方计算)作为预格式化文本输入(或者更确切地说是导入/粘贴),以便Calc不会使显示屏变脏.仍然可以通过应用VALUE()函数来引用数字,对于许多内联计算,内部精度非常充足 - 尤其对于图形化.

下图显示了我在其中一条评论中发布的内容,即内部精度高于显示的内容.如果程序没有显示它们,我们如何才能找出实际值是什么?通过添加/减去小值,观察更改,创建和测试关于实际值的关系,假设的舍入行为和显示值的假设来解决问题?真正令人难以置信的是.

相同的显示值但行为不同

我正在为以下任何一项提供奖励:

  • 一种实用的方法,在所见即所得的意义上恢复Calc的理智行为(你看到的是什么内部,或者更确切地说,如果它在里面然后它可以显示)而不降低内部精度并且不用分支整个血腥源树并自己修复它

  • 指向电子表格的指针,其精度高于IEEE 754双倍(最好是任意精度,如GP/PARI,但作为电子表格),是公共域或共享软件; 在线/云计算的东西是可以接受的

第一项的原因有两个:一方面,当电子表格精度低于通用IEEE 754双精度时,这是一种血腥的麻烦,因为这意味着关于该基线水平的准确度/精度/稳定性的经验/知识不会延续.另一方面,如果我们不能相信显示的值是正确的,即使我们确切知道实际值是正确的,也会产生更大的麻烦.

第二个项目的原因很简单,在另一个程序中编写用于高精度计算事物或使用bignums的东西,或者为此目的编辑/编译/运行程序是相当麻烦的.除了笨拙地分成电子表格和一堆脚本或源文件之外,在电子表格内部工作更加自然和方便.

precision spreadsheet floating-accuracy arbitrary-precision libreoffice-calc

12
推荐指数
1
解决办法
1582
查看次数

Win32命名管道和邮件大小限制 - 仍然适用旧的64K限制?

Win32曾经有消息模式管道的消息大小限制为64K,如KB文章Q119218 PRB:Named Pipe Write()限制为64K 所见."适用于"部分仅列出"Microsoft Win32应用程序编程接口",文章相当陈旧; 没有迹象表明它是否也适用于Windows 7等合理的当前版本.是否有关于该问题的可靠,最新信息?

当前的在线文档仅包含未指定限制的模糊提示,例如CreateNamedPipe()函数文档中的这个漂亮的措辞:

输入和输出缓冲区大小是建议性的.为命名管道的每一端保留的实际缓冲区大小是系统默认值,系统最小值或最大值,或指定的大小向上舍入到下一个分配边界.

没有迹象表明"系统最大值"可能是什么,或者如何查询其值.

TransactNamedPipe()的文档中再次出现64K限制:

命名管道事务的最大保证大小为64千字节.在某些有限的情况下,超过64千字节的事务是可能的,具体取决于参与事务的操作系统版本和动态网络条件.但是,无法保证64千字节以上的交易能够成功.

但是,很可能该限制仅适用于命名管道"交易" TransactNamedPipe(); 也就是说,写入后跟读取,全部包含在单个系统调用和/或网络事务中.该限制可能与SMB有关,因此不适用于本地管道.这有什么硬信息吗?

消息模式管道非常适合当前项目,其中服务器进程获取请求数据包并提供单个响应数据包,调度程序是Apache中托管的简单多线程存根(类似于mod_fcgid).字节模式管道需要一些额外的框架,这使得消息模式管道看起来更简单,因此更可取.但是,不能将请求和响应大小限制为64K; 因此这个问题.

windows winapi named-pipes

5
推荐指数
1
解决办法
3837
查看次数

Delphi:如何表达一个空的 TDateTime?

是否可以将空(零)TDateTime 值表示为常量?我试过TDateTime(0),TDateTime(0.0)和其他东西,但编译器 (Delphi 7) 没有留下深刻的印象。

目前我正在使用一个初始化的全局变量:

const
   TDateTime_0: TDateTime = 0.0;
Run Code Online (Sandbox Code Playgroud)

这样的作品。然而,我只是继承了一大堆很好的Delphi 7代码,而且我已经好久没有使用Turbo Pascal了......这意味着我真的需要刷我的Delphi fu,这让我想知道。

相比之下,编译器对类似Integer(0). 它分配给一个变体的结果是类型 0 的值ftInteger,而分配一个普通文字 0 将导致一个类型的变体ftSmallInt

澄清:目标是将特定类型的“空”值传递给采用变体的函数(包括编译器管理的变体数组,称为“常量数组”,以及诸如 TParameter.Value 之类的设置器)。

对 Ken White 的澄清:这里的问题本质上是类型推导和重载解析;上面提到的“采用变体的函数”只是一个特例。文字0and0.0可以隐式转换为TDateTime,这就是为什么它们可以分配给该类型的容器(变量、记录字段),并且它们可以用于初始化此类容器(即函数参数),无需多说。但是,当编译器需要进行类型推导时,情况发生了变化:

procedure foo (value: Double); overload; 
procedure foo (value: TDateTime); overload;
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,底层类型都是 Double,这意味着编译器需要显式键入参数(即,使用纯文字的调用被拒绝为不明确的)。对于基于序数的类型,显式类型没有问题,但类型 Double 有问题,需要将值填充到类型化容器中才能使用它们。可编译示例(需要比 Delphi 7 新的 Delphi):

type
   TSomeId = type Integer;

procedure foo (value: Integer  ); overload;  begin  WriteLn('Integer   ', value);  end;
procedure …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-7

5
推荐指数
1
解决办法
3886
查看次数

埃拉托斯特尼筛法有巨大的“透支”——到底桑达拉姆筛法更好吗?

标准埃拉托斯特尼筛法多次剔除大多数复合材料;事实上,唯一不会被标记多次的就是那些恰好是两个素数的乘积。当然,随着筛子变大,透支也会增加。

对于奇数筛(即没有偶数),透支达到 100%(n = 3,509,227),其中有 1,503,868 个复合值和 1,503,868 个已划掉的数字的划掉。对于 n = 2^32,透支上升至 134.25%(透支 2,610,022,328 与弹出计数 1,944,203,427 = (2^32 / 2) - 203,280,221)。

当且仅当循环限制是智能计算的时, Sundaram 筛法(在maths.org上有另一种解释)可能会更聪明一些。然而,我所看到的消息来源似乎将其掩盖为“优化”,而且似乎未优化的 Sundaram 每次都会被仅赔率的埃拉托色尼击败。

有趣的是,两者都创建了完全相同的最终位图,即位图 k 对应于数字 (2 * k + 1)。因此,两种算法最终必须设置完全相同的位,只是它们的处理方式不同。

有人拥有竞技性、调校 Sundaram 的实践经验吗?它能打败古希腊语吗?

我精简了小因子筛的代码(2^32,仅赔率的希腊语),并将段大小调整为 256 KB,这对于具有 256 KB L2 的旧 Nehalem 和较新的 CPU 来说都是最佳的(甚至尽管后者对更大的细分市场更加宽容)。但现在我已经碰壁了,该死的筛子仍然需要 8.5 秒来初始化。从硬盘加载筛子并不是一个非常有吸引力的选择,并且多线程很难以可移植的方式完成(因为像 boost 这样的库往往会增加可移植性)...

Sundaram 能否将启动时间缩短几秒钟?

PS:透支本身不是问题,会被二级缓存吸收。关键是,标准的埃拉托斯特尼似乎做了比必要的工作多一倍的工作,这表明可能有可能更快地完成更少的工作。

primes sieve sieve-of-eratosthenes

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

LINQPad:Assert()打印"失败:"并继续而不是破坏

在LINQPad,Debug.Assert()Trace.Assert()System.Diagnostics命名空间不会达到预期效果.

而不是破坏 - 即弹出一个消息框或其他恰好配置的东西<trace>- 它们只是将"失败:"或"Fehler:"打印到输出窗口,让程序以其快乐的方式继续.换句话说,除了嘈杂,不可忽视的爆炸之外,只有近乎看不见的微屁,将"失败:"散布在文本输出中.

有没有办法Assert()恢复到LINQPad下的默认行为?

或者,是否有一种简单的Trace.Assert()模拟方法,以便失败导致嘈杂的爆炸(例外,消息框,无论如何),故障的来源以行号或类似的形式确定?

我的单元测试是基于的Trace.Assert(),如果函数在失败时不能破坏程序,它们就完全没用了.

在Visual Studio中,一切正常但在LINQPad中没有.我没有摆弄任何系统范围的设置,但我确实在某个时间点安装了Mono.我在LINQPad的所有设置中使用精细的梳子,但无济于事.LINQPad版本为4.57.02(非免费),在Windows 7 Pro(德语)和Windows 8.1 Pro(英语)上运行.

我用google搜索高,宽,但我唯一能找到的是Trace.Assert没有破坏的主题,也没有在Stack Overflow上显示消息框.它的标题看起来很有希望,但其中的答案却没有.

PS:我试着通过添加进行模拟

class Trace
{
    public static void Assert (bool condition)
    {
        if (!condition)
            throw new Exception("FAIL!");
    }
}
Run Code Online (Sandbox Code Playgroud)

到LINQ脚本并在throw语句上设置断点.单击LINQPad调试器中的相关调用堆栈条目将我带到相关的源代码行,因此这种方法很有效.但是,我无法找到与FoxPro SET DEBUG ON直接从源代码调用调试器的等价物,而不必在throw... 上设置断点.

c# linqpad

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