草庐IT

c++ - Visual Studio 调试与发布版本 : comparing int and float missmatch

coder 2023-11-15 原文

看看这个例子:

#include <stdio.h>

int main() {

  int i= 16777217;
  float f = 16777216.0;
  float g = i;

  if( i == f )
    printf("eq\n");
  else
    printf("neq\n");

  if( g == f )
    printf("eq\n");
  else
    printf("neq\n");

  return 0;
}

在 Release模式、gcc 或 g++ (4.9.2) 中使用 Visual Studio 2010 C++ (VS),具有输出

eq
eq

这对我来说是合理的:在第一次比较期间,i 被隐式转换为 float ,其中尾数中的有效位被截断。因此,if 都具有相同的位模式,相当于相等性。在第二个 if 中应用相同的转换,但在定义和初始化 g 时已经执行。

但是,在 Debug模式下使用VS,结果是

neq
eq

看起来,第一个 if 中比较期间的隐式转换(作为 C 和 C++ 中常用算术转换的一部分)没有应用。这是真的?是否有一种 VS 机制可以防止在比较 float 和整数时出现此类误报(更精确地转换为 int/float)?根据MSDN VS C++ 遵循标准。

我已经用 this function 检查了位表示.对于所有编译器,它产生

i = 00000001000000000000000000000001
f = 01001011100000000000000000000000
g = 01001011100000000000000000000000
VS 上的

float.h 声明 #define FLT_MANT_DIG 24 因此所描述的截断问题也应该成立。

我在同一台机器(Intel i5-3570K)上编译了所有内容,但在虚拟框中编译了 VS。在另一台机器上用 VS 编译也会打印 neq/eq

编辑:附加汇编代码

差异_调试.asm

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE   c:\Users\user\documents\visual studio 2010\Projects\differences\differences\differences.cpp
    .686P
    .XMM
    include listing.inc
    .model  flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC  ??_C@_04LMPLCMBC@neq?6?$AA@         ; `string'
PUBLIC  ??_C@_03HNJPMNDP@eq?6?$AA@          ; `string'
PUBLIC  __real@4b800000
PUBLIC  _wmain
EXTRN   __imp__printf:PROC
EXTRN   __fltused:DWORD
EXTRN   __RTC_CheckEsp:PROC
EXTRN   __RTC_Shutdown:PROC
EXTRN   __RTC_InitBase:PROC
;   COMDAT ??_C@_04LMPLCMBC@neq?6?$AA@
; File c:\users\user\documents\visual studio 2010\projects\differences\differences\differences.cpp
CONST   SEGMENT
??_C@_04LMPLCMBC@neq?6?$AA@ DB 'neq', 0aH, 00H      ; `string'
CONST   ENDS
;   COMDAT ??_C@_03HNJPMNDP@eq?6?$AA@
CONST   SEGMENT
??_C@_03HNJPMNDP@eq?6?$AA@ DB 'eq', 0aH, 00H        ; `string'
CONST   ENDS
;   COMDAT __real@4b800000
CONST   SEGMENT
__real@4b800000 DD 04b800000r           ; 1.67772e+007
CONST   ENDS
;   COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
;   COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ ENDS
;   COMDAT _wmain
_TEXT   SEGMENT
_g$ = -32                       ; size = 4
_f$ = -20                       ; size = 4
_i$ = -8                        ; size = 4
_argc$ = 8                      ; size = 4
_argv$ = 12                     ; size = 4
_wmain  PROC                        ; COMDAT
; Line 7
    push    ebp
    mov ebp, esp
    sub esp, 228                ; 000000e4H
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-228]
    mov ecx, 57                 ; 00000039H
    mov eax, -858993460             ; ccccccccH
    rep stosd
; Line 8
    mov DWORD PTR _i$[ebp], 16777217        ; 01000001H
; Line 9
    fld DWORD PTR __real@4b800000
    fstp    DWORD PTR _f$[ebp]
; Line 10
    fild    DWORD PTR _i$[ebp]
    fstp    DWORD PTR _g$[ebp]
; Line 13
    fild    DWORD PTR _i$[ebp]
    fld DWORD PTR _f$[ebp]
    fucompp
    fnstsw  ax
    test    ah, 68                  ; 00000044H
    jp  SHORT $LN4@wmain
; Line 14
    mov esi, esp
    push    OFFSET ??_C@_03HNJPMNDP@eq?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4
    cmp esi, esp
    call    __RTC_CheckEsp
; Line 15
    jmp SHORT $LN3@wmain
$LN4@wmain:
; Line 16
    mov esi, esp
    push    OFFSET ??_C@_04LMPLCMBC@neq?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4
    cmp esi, esp
    call    __RTC_CheckEsp
$LN3@wmain:
; Line 19
    fld DWORD PTR _g$[ebp]
    fld DWORD PTR _f$[ebp]
    fucompp
    fnstsw  ax
    test    ah, 68                  ; 00000044H
    jp  SHORT $LN2@wmain
; Line 20
    mov esi, esp
    push    OFFSET ??_C@_03HNJPMNDP@eq?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4
    cmp esi, esp
    call    __RTC_CheckEsp
; Line 21
    jmp SHORT $LN1@wmain
$LN2@wmain:
; Line 22
    mov esi, esp
    push    OFFSET ??_C@_04LMPLCMBC@neq?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4
    cmp esi, esp
    call    __RTC_CheckEsp
$LN1@wmain:
; Line 24
    xor eax, eax
; Line 26
    pop edi
    pop esi
    pop ebx
    add esp, 228                ; 000000e4H
    cmp ebp, esp
    call    __RTC_CheckEsp
    mov esp, ebp
    pop ebp
    ret 0
_wmain  ENDP
_TEXT   ENDS
END

differences_release.asm

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE   c:\Users\user\documents\visual studio 2010\Projects\differences\differences\differences.cpp
    .686P
    .XMM
    include listing.inc
    .model  flat

INCLUDELIB OLDNAMES

PUBLIC  ??_C@_03HNJPMNDP@eq?6?$AA@          ; `string'
PUBLIC  ??_C@_04LMPLCMBC@neq?6?$AA@         ; `string'
EXTRN   @__security_check_cookie@4:PROC
EXTRN   __imp__printf:PROC
;   COMDAT ??_C@_04LMPLCMBC@neq?6?$AA@
CONST   SEGMENT
??_C@_04LMPLCMBC@neq?6?$AA@ DB 'neq', 0aH, 00H      ; `string'
CONST   ENDS
;   COMDAT ??_C@_03HNJPMNDP@eq?6?$AA@
CONST   SEGMENT
??_C@_03HNJPMNDP@eq?6?$AA@ DB 'eq', 0aH, 00H        ; `string'
CONST   ENDS
PUBLIC  _wmain
EXTRN   __fltused:DWORD
; Function compile flags: /Ogtp
;   COMDAT _wmain
_TEXT   SEGMENT
_argc$ = 8                      ; size = 4
_argv$ = 12                     ; size = 4
_wmain  PROC                        ; COMDAT
; File c:\users\user\documents\visual studio 2010\projects\differences\differences\differences.cpp
; Line 7
    push    esi
; Line 14
    mov esi, DWORD PTR __imp__printf
    push    OFFSET ??_C@_03HNJPMNDP@eq?6?$AA@
    call    esi
; Line 20
    push    OFFSET ??_C@_03HNJPMNDP@eq?6?$AA@
    call    esi
    add esp, 8
; Line 24
    xor eax, eax
    pop esi
; Line 26
    ret 0
_wmain  ENDP
_TEXT   ENDS
END

最佳答案

如果我们分解发布的 ASM:

; Line 14
    push    OFFSET ??_C@_03HNJPMNDP@eq?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4
; Line 18
    xor eax, eax
; Line 20
    ret 0

它只是打印 eq 并退出,这表明 float 比较刚刚被完全优化掉。对于调试程序集,我们看到它使用 fldfild 指令:

; Line 9
    fld DWORD PTR __real@4b800000
    fstp    DWORD PTR _f$[ebp]
; Line 10
    fild    DWORD PTR _i$[ebp]
    fstp    DWORD PTR _g$[ebp]
; Line 13
    fild    DWORD PTR _i$[ebp]

这些是 IA32 指令,这是 Visual Studio 2010 中使用的默认架构。我怀疑您使用 /arch:SSE2 而不是您会得到不同的结果。

Hans Passant's comment基本上证实了我刚才所说的。

关于c++ - Visual Studio 调试与发布版本 : comparing int and float missmatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37162422/

有关c++ - Visual Studio 调试与发布版本 : comparing int and float missmatch的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

  7. ruby - JetBrains RubyMine 3.2.4 调试器不工作 - 2

    使用Ruby1.9.2运行IDE提示说需要gemruby​​-debug-base19x并提供安装它。但是,在尝试安装它时会显示消息Failedtoinstallgems.Followinggemswerenotinstalled:C:/ProgramFiles(x86)/JetBrains/RubyMine3.2.4/rb/gems/ruby-debug-base19x-0.11.30.pre2.gem:Errorinstallingruby-debug-base19x-0.11.30.pre2.gem:The'linecache19'nativegemrequiresinstall

  8. ruby-on-rails - 如何调试 cucumber 测试? - 2

    我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element

  9. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  10. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

随机推荐