val = -6.965998958219366E-018注意变量val的值。在两种情况下是不同的。我使用的ifort版本是isifort --versionifort(IFORT)9.0 20050430Copyright(C)1985-2005 Intel 公司。保留所有权利.icc的版本是> icc --versionicc (ICC)9.0 20050430Copyright(C)1985-2005 Intel Corporation。所有权利 保留。文件binary_file被附上。从那个计算看起来像 子程序read_do_calc()的非平凡程序中捕获了 。有人可以帮助我吗?我错了什么 这次?谢谢.NM 解决方案 NM写道: 有时前我在C ++和Fortran 程序之间的链接方面存在问题。使用Fortran 关键字序列解决了这个问题(使用来自此新闻组的输入)。与派生类型(假设连续空间)。 现在我又遇到了问题。为了显示我创建的小程序的问题,这次在C ++和Fortran之间没有传递数据结构。 (剪辑) val = a +(b * c * d *(e * e))* f (剪辑) -0.430331482911935 1.00000000000000 -0.774596669241483 -1.00000000000000 2.00000000000000 0.138888888888889 val = 0.000000000000000E + 000 (剪辑) -0.430331482911935 1.00000000000000 -0.774596669241483 -1.00000000000000 2.00000000000000 0.138888888888889 val = -6.965998958219366E-018 注意变量val的值在这两种情况下是不同的。我正在使用的ifort版本是 关于这一点,我可以说很多事情。 首先,使用主程序 的语言总是做I / O可能更好。有时需要初始化I / O系统。 这比以前少了一个问题,因为许多人使用一个库 来进行实际的I / O在这两种情况下。 一般来说,一个人不应该依赖浮点数的确切结果,特别是在减去非常相似的数字的时候。 我在这种情况下的猜测是Fortran主程序将 浮点处理器设置为53位精度,其中C ++设置 或离开它64.允许编译器以比所要求的更精确的方式执行算术的规则是复杂的, 以及C ++和Fortran之间的不同。 无论如何,期待一个答案或另一个答案浮动 点,我相信是没有根据的。 - 格伦 在文章< dg ********** @ news.cs.utexas.edu>," NM" < [email protected]>写道: ..... val = a +(b * c * d *(e * e))* f .... ./ fort_prog .... val = 0.000000000000000E + 000 ./ cpp_prog val = -6.965998958219366E-018 请注意变量val的值。两种情况不同。 肯定不是*非常*不同。不同之处在于双精度准确度对于b $ b的预期是什么。 有谁可以帮助我?这次我做错了什么? 你所做的错误是希望从b 浮点运算得到完美的准确性。这与编程 语言几乎没有关系。它是典型计算机算术实现的基本属性。你需要阅读这个主题。 文件< http://docs.sun.com/source/806-3568/ncg_goldberg.html>是一个优秀的,经常被引用的主题治疗方法(实际上,在大约一天左右的时间里,它在另一个帖子中引用了 )。 除了那些基本材料,你还需要了解一个 给定的表达式可能会在不同的 编译器中以不同的方式实现,甚至使用相同编译器的不同选项。那些不同的实现可能涉及不同的排序 操作或 寄存器中中间值存储的差异。这些差异可以并且确实经常导致四舍五入的差异。 由于这些因素,期望结果是错误的除了某些特殊的 情况外,浮点运算确切......而且你没有这些情况。浮点 操作通常应视为近似值。您可以根据需要选择适当的精度来保证应用程序的近似值合理 ,但您无法合理地预期事情是准确的。 你做错了什么是期待确切的结果。 您所看到的差异大约是预期的大小 简单的舍入情况错误。对于数值不稳定的算法, 这种微小的差异有时会变得非常大。也许 这是你在实际的 申请中引起你注意的问题。 (这通常表明东方有理由质疑所用算法的适用性)。测试精确 值的算法表现得特别糟糕。 如果你说我理解这一切,但......(插入) 这里的任何东西),然后我害怕你真的不明白。它确实是&b $ b跟随但是之后的内容并不重要。特别是, 的任何变体,但它在两种语言中都是相同的表达式。表示 你真的不明白。 - Richard Maine |良好的判断来自经验; 电子邮件:我的第一个.last org.domain |经验来自糟糕的判断。 org:nasa,domain:gov | - 马克吐温 Richard E Maine写道: (剪辑) 肯定不是*非常*不同。关于双精度精度的预期差异是正确的。 (剪辑) 你所做的错误是希望从浮点算术中获得完美的准确性。这与编程语言几乎没有关系。它是典型的计算机算法实现的基本属性。你需要阅读这个主题。 文件< http://docs.sun.com/source/806-3568/ncg_goldberg.html>是一个优秀的,经常被引用的主题治疗方法(实际上,它在大约一天前的另一个主题中引用了)。 我100%同意,如果他期望更多浮点数,那就是错误的b $ ba $ 除了那个基本的材料,您还需要了解,给定的表达式可能在不同的编译器中以不同的方式实现,甚至可能在同一编译器的不同选项中实现。那些不同的实现可能涉及诸如操作的不同排序或者在寄存器中存储中间值的差异之类的事情。这些差异可能并且确实经常导致四舍五入的差异。 但在这种情况下,它是相同的目标程序。他从C ++或Fortran主程序调用 子程序,只编译一次。 所有计算都在子程序中完成。 由于这些因素,除了某些特殊的情况外,期望浮点运算的结果是准确的是错误的...而且你没有这些情况。浮点操作通常应视为近似值。您可以根据需要选择合适的精度来保持应用程序的近似值,但是您无法合理地预期事情是准确的。您做错了什么是期待准确的结果。 是的。请注意,同一程序中不同行的相同 表达式也存在类似差异。 (剪辑) 如果你说我理解所有这一切,但......(在这里插入任何东西),那么我恐怕你们真的不明白。它真的没关系但是之后的内容。特别是,两种语言中的相同表达都是的任何变体。会表明你并不理解。 我不完全确定我理解x87漂浮的方式 点处理器已初始化,但甚至可能运行相同的.EXE文件并获得不同的结果。。如果 库没有初始化x87控制寄存器,并且 操作系统没有,那么你可以得到之前的任何东西。 如果你想要精确的结果,不要使用浮点数。 - glen Sometimes ago I was having a problem in linking between C++ and Fortranprogram. That was solved (using input from this newsgroup) using the Fortrankeyword "sequence" with the derived types (to assume contiguous space).Now I am having problem again. In order to show the problem I have createdsmall program and this time there is no data straucture being passed betweenC++ and Fortran.Here is how the program looks likefile read_do_calc.f=================== subroutine read_do_calc()double precision :: a,b,c,d,e,f,valopen(60,file=''binary_file'',status=''unknown'',form='' unformatted'')read(60) aread(60) bread(60) cread(60) dread(60) eread(60) fclose(60)write(*,*) a,'' '',b,'' '',c,'' '',d,'' '',e,'' '',fval = a + (b*c*d*(e*e))*fwrite(*,*) ''val = '',valreturnendfile fort_main.f================ program maincall read_do_calc()endprogram mainfile main.cpp============= extern "C" {void read_do_calc_(void);}int main(void){read_do_calc_();return 0;} compile read_do_calc.fifort -c read_do_calc.fcreate the fortran programifort -o fort_prog fort_main.f read_do_calc.ocreate the c++ program (either using icc or g++ , it did not matter in mycase)icc -o cpp_prog main.cppread_do_calc.o -L/lusr/share/software/intel/lib -lifcoreoutput of the two programs given below./fort_prog-0.430331482911935 1.00000000000000 -0.774596669241483-1.00000000000000 2.00000000000000 0.138888888888889val = 0.000000000000000E+000./cpp_prog-0.430331482911935 1.00000000000000 -0.774596669241483-1.00000000000000 2.00000000000000 0.138888888888889val = -6.965998958219366E-018Notice the value of the variable "val" isdifferent in the two cases.The version of ifort I am using isifort --versionifort (IFORT) 9.0 20050430Copyright (C) 1985-2005 IntelCorporation. All rights reserved.and the version of icc is>icc --versionicc(ICC) 9.0 20050430Copyright (C) 1985-2005 Intel Corporation. All rightsreserved.The file "binary_file" is attached. The values there was capturedfrom a nontrivial program whose computation looks like that of thesubroutine read_do_calc().Can anyone please help me? What am I doing wrongthis time? Thanks.NM 解决方案 NM wrote: Sometimes ago I was having a problem in linking between C++ and Fortran program. That was solved (using input from this newsgroup) using the Fortran keyword "sequence" with the derived types (to assume contiguous space). Now I am having problem again. In order to show the problem I have created small program and this time there is no data straucture being passed between C++ and Fortran.(snip) val = a + (b*c*d*(e*e))*f(snip) -0.430331482911935 1.00000000000000 -0.774596669241483 -1.00000000000000 2.00000000000000 0.138888888888889 val = 0.000000000000000E+000(snip) -0.430331482911935 1.00000000000000 -0.774596669241483 -1.00000000000000 2.00000000000000 0.138888888888889 val = -6.965998958219366E-018 Notice the value of the variable "val" is different in the two cases.The version of ifort I am using isThere are a number of things I could say about this.First, it is probably better to always do I/O using the language ofthe main program. Sometimes the I/O system needs to be initialized.This is less a problem than it used to be, as many use one libraryto do the actual I/O in both cases.In general, one should not rely on exact results from floating point,especially when subtracting very similar numbers.My guess in this case is that the Fortran main program sets thefloating point processor to 53 bit precision, where C++ setsor leaves it at 64. The rules for allowing the compiler to doarithmetic with more precision than is asked for are complicated,and different between C++ and Fortran.In any case, expecting one answer or the other from floatingpoint is, I believe, unwarranted.-- glen In article <dg**********@news.cs.utexas.edu>, "NM" <[email protected]> wrote:..... val = a + (b*c*d*(e*e))*f...../fort_prog.... val = 0.000000000000000E+000./cpp_prog val = -6.965998958219366E-018 Notice the value of the variable "val" is different in the two cases.It sure isn''t *VERY* different. The difference is right about what onewould expect for double precision accuracy. Can anyone please help me? What am I doing wrong this time?What you are doing wrong is expecting perfect accuracy fromfloating-point arithmetic. This has very little to do with programminglanguages. It is instead a fundamental property of typical computerimplementations of arithmetic. You need to read up on that subject. Thedocument <http://docs.sun.com/source/806-3568/ncg_goldberg.html> is anexcellent and oft-cited treatment of the subject (in fact, it was citedin another thread here just a day or so ago).In addition to that basic material, you also need to understand that agiven expression might be implemented differently in differentcompilers, or even with different options of the same compiler. Thosedifferent implementations can involve such things as different orderingof operations or differences in storage of intermediate values inregisters. These differences can and do often result in differences inrounding.Because of these factors, it is a mistake to expect the results offloating point operations to be exact except in some specialcircumstances... and you don''t have those circumstances. Floating pointoperations should generally be viewed as approximations. You can selectan appropriate precision as needed to keep the approximations reasonablefor an application, but you can''t reasonably expect things to be exact.What you are doing wrong is expecting exact results.The differences you are seeing are right around the size expected fromsimple cases of rounding error. With numerically unstable algorithms,such small differences can sometimes grow to be quite large. Perhapsthat''s what drew your attention to the problem in the actualapplication. (That generally indicates at east reason to question thesuitability of the algorithm used). ALgorithms that test for exactvalues can behave particularly poorly.And if you say something like "I understand all that, but...(insertanything here)", then I''m afraid you didn''t really understand. It reallydoesn''t matter what follows the "but". In particular, any variation of"but it was the same expression in both languages" would indicate thatyou didn''t really understand.--Richard Maine | Good judgment comes from experience;email: my first.last at org.domain | experience comes from bad judgment.org: nasa, domain: gov | -- Mark TwainRichard E Maine wrote:(snip) It sure isn''t *VERY* different. The difference is right about what one would expect for double precision accuracy.(snip) What you are doing wrong is expecting perfect accuracy from floating-point arithmetic. This has very little to do with programming languages. It is instead a fundamental property of typical computer implementations of arithmetic. You need to read up on that subject. The document <http://docs.sun.com/source/806-3568/ncg_goldberg.html> is an excellent and oft-cited treatment of the subject (in fact, it was cited in another thread here just a day or so ago).I 100% agree, if he expects more from floating point, that isa mistake. In addition to that basic material, you also need to understand that a given expression might be implemented differently in different compilers, or even with different options of the same compiler. Those different implementations can involve such things as different ordering of operations or differences in storage of intermediate values in registers. These differences can and do often result in differences in rounding.In this case, though, it is the same object program. He calls thesubroutine, compiled only once, from a C++ or Fortran main program.All the calculation is done in the subroutine. Because of these factors, it is a mistake to expect the results of floating point operations to be exact except in some special circumstances... and you don''t have those circumstances. Floating point operations should generally be viewed as approximations. You can select an appropriate precision as needed to keep the approximations reasonable for an application, but you can''t reasonably expect things to be exact. What you are doing wrong is expecting exact results.Yes. Note that similar differences have been seen for the sameexpression at a different line in the same program.(snip) And if you say something like "I understand all that, but...(insert anything here)", then I''m afraid you didn''t really understand. It really doesn''t matter what follows the "but". In particular, any variation of "but it was the same expression in both languages" would indicate that you didn''t really understand.I am not completely sure I understand the way the x87 floatingpoint processor is initialized, but it might even be possibleto run the same .EXE file and get different results. If thelibrary doesn''t initialize the x87 control register, and theOS doesn''t, you get whatever was there before.If you want exact results don''t use floating point.-- glen 这篇关于再次:C ++和Fortran之间的链接导致错误的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-22 15:34