返回介绍

25.2 浮点数值

发布于 2025-02-22 14:00:49 字数 4402 浏览 0 评论 0 收藏 0

清单 11.1: MSVC 2010

#!cpp
#include <stdio.h>
#include <stdlib.h>
int main()
{
    double celsius, fahr;
    printf ("Enter temperature in Fahrenheit:\n");
    if (scanf ("%lf", &fahr)!=1)
    {
        printf ("Error while parsing your input\n");
        exit(0);
    };
    celsius = 5 * (fahr-32) / 9;
    if (celsius<-273)
    {
        printf ("Error: incorrect temperature!\n");
        exit(0);
    };
    printf ("Celsius: %lf\n", celsius);
};

MSVC 2010 x86 使用 FPU 指令...

清单 25.2: MSVC 2010 x86 /Ox

#!bash
$SG4038 DB ’Enter temperature in Fahrenheit:’, 0aH, 00H
$SG4040 DB ’%lf’, 00H
$SG4041 DB ’Error while parsing your input’, 0aH, 00H
$SG4043 DB ’Error: incorrect temperature!’, 0aH, 00H
$SG4044 DB ’Celsius: %lf’, 0aH, 00H
__real@c071100000000000 DQ 0c071100000000000r ; -273
__real@4022000000000000 DQ 04022000000000000r ; 9
__real@4014000000000000 DQ 04014000000000000r ; 5
__real@4040000000000000 DQ 04040000000000000r ; 32
_fahr$ = -8 ; size = 8
_main PROC
    sub esp, 8
    push esi
    mov esi, DWORD PTR __imp__printf
    push OFFSET $SG4038 ; ’Enter temperature in Fahrenheit:’
    call esi ; call printf
    lea eax, DWORD PTR _fahr$[esp+16]
    push eax
    push OFFSET $SG4040 ; ’%lf’
    call DWORD PTR __imp__scanf
    add esp, 12 ; 0000000cH
    cmp eax, 1
    je SHORT $LN2@main
    push OFFSET $SG4041 ; ’Error while parsing your input’
    call esi ; call printf
    add esp, 4
    push 0
    call DWORD PTR __imp__exit
    $LN2@main:
    fld QWORD PTR _fahr$[esp+12]
    fsub QWORD PTR __real@4040000000000000 ; 32
    fmul QWORD PTR __real@4014000000000000 ; 5
    fdiv QWORD PTR __real@4022000000000000 ; 9
    fld QWORD PTR __real@c071100000000000 ; -273
    fcomp ST(1)
    fnstsw ax
    test ah, 65 ; 00000041H
    jne SHORT $LN1@main
    push OFFSET $SG4043 ; ’Error: incorrect temperature!’
    fstp ST(0)
    call esi ; call printf
    add esp, 4
    push 0
    call DWORD PTR __imp__exit
    $LN1@main:
    sub esp, 8
    fstp QWORD PTR [esp]
    push OFFSET $SG4044 ; ’Celsius: %lf’
    call esi
    add esp, 12 ; 0000000cH
    ; return 0
    xor eax, eax
    pop esi
    add esp, 8
    ret 0
$LN10@main:
_main ENDP

但是 MSVC 从 2012 年开始又改成了使用 SIMD 指令:

清单 25.3: MSVC 2010 x86 /Ox

#!bash
$SG4228 DB ’Enter temperature in Fahrenheit:’, 0aH, 00H
$SG4230 DB ’%lf’, 00H
$SG4231 DB ’Error while parsing your input’, 0aH, 00H
$SG4233 DB ’Error: incorrect temperature!’, 0aH, 00H
$SG4234 DB ’Celsius: %lf’, 0aH, 00H
__real@c071100000000000 DQ 0c071100000000000r ; -273
__real@4040000000000000 DQ 04040000000000000r ; 32
__real@4022000000000000 DQ 04022000000000000r ; 9
__real@4014000000000000 DQ 04014000000000000r ; 5
_fahr$ = -8 ; size = 8
_main PROC
    sub esp, 8
    push esi
    mov esi, DWORD PTR __imp__printf
    push OFFSET $SG4228 ; ’Enter temperature in Fahrenheit:’
    call esi ; call printf
    lea eax, DWORD PTR _fahr$[esp+16]
    push eax
    push OFFSET $SG4230 ; ’%lf’
    call DWORD PTR __imp__scanf
    add esp, 12 ; 0000000cH
    cmp eax, 1
    je SHORT $LN2@main
    push OFFSET $SG4231 ; ’Error while parsing your input’
    call esi ; call printf
    add esp, 4
    push 0
    call DWORD PTR __imp__exit
    $LN9@main:
    $LN2@main:
    movsd xmm1, QWORD PTR _fahr$[esp+12]
    subsd xmm1, QWORD PTR __real@4040000000000000 ; 32
    movsd xmm0, QWORD PTR __real@c071100000000000 ; -273
    mulsd xmm1, QWORD PTR __real@4014000000000000 ; 5
    divsd xmm1, QWORD PTR __real@4022000000000000 ; 9
    comisd xmm0, xmm1
    jbe SHORT $LN1@main
    push OFFSET $SG4233 ; ’Error: incorrect temperature!’
    call esi ; call printf
    add esp, 4
    push 0
    call DWORD PTR __imp__exit
    $LN10@main:
    $LN1@main:
    sub esp, 8
    movsd QWORD PTR [esp], xmm1
    push OFFSET $SG4234 ; ’Celsius: %lf’
    call esi ; call printf
    add esp, 12 ; 0000000cH
    ; return 0
    xor eax, eax
    pop esi
    add esp, 8
    ret 0
$LN8@main:
_main ENDP

当然,SIMD 在 x86 下也是可用的,包括这些浮点数的运算。使用他们计算起来也确实方便点,所以微软编译器使用了他们。 我们也可以注意到 -273 这个值会很早的被载入 XMM0。这个没问题,因为编译器并不一定会按照源代码里面的顺序产生代码。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文