Сообщение Re: [StackOverflow] вопросы недели от 01.12.2016 18:11
Изменено 23.08.2025 21:30 netch80
Re: [StackOverflow] вопросы недели
Здравствуйте, Sinix, Вы писали:
S>1. Красивейший гейзенбаг:
Запощу для архива аналог для C.
fpsetprec это для FreeBSD, для других платформ _controlfp и тому подобное. FP_PS ставит точность на single, ответ — 1. FP_PD (double), FP_PE (extended) приводит к ответу 0. Разумеется, компиляция должна быть с использованием FPU (умолчание для 32 бит), на SSE не повторяется. От уровня отладки не зависит, благодаря volatile.
В ассемблере получается
и за счёт сравнения на стеке FPU при более широкой точности — получается данный эффект.
В стандарте C возможность подобного определяется макросом FLT_EVAL_METHOD, но в этих тестах он был равен -1, что значит, что нет определённости на этапе компиляции. Для 64-битного режима с использованием SSE он равен 0.
В дотнете, как я понял, спросить это нет возможности.
S>1. Красивейший гейзенбаг:
Запощу для архива аналог для C.
#include <stdio.h>
#include <ieeefp.h>
volatile float a, b, f1;
int main() {
fpsetprec(FP_PD);
a = 0.1f;
b = 0.2f;
f1 = a + b;
printf("%d\n", f1 == (a + b));
return 0;
}fpsetprec это для FreeBSD, для других платформ _controlfp и тому подобное. FP_PS ставит точность на single, ответ — 1. FP_PD (double), FP_PE (extended) приводит к ответу 0. Разумеется, компиляция должна быть с использованием FPU (умолчание для 32 бит), на SSE не повторяется. От уровня отладки не зависит, благодаря volatile.
В ассемблере получается
80485c8: d9 05 b8 98 04 08 flds a
80485ce: d9 05 c0 98 04 08 flds b
80485d4: de c1 faddp %st,%st(1)
80485d6: d9 1d bc 98 04 08 fstps f1
80485dc: d9 05 bc 98 04 08 flds f1
80485e2: d9 05 b8 98 04 08 flds a
80485e8: d9 05 c0 98 04 08 flds b
80485ee: de c1 faddp %st,%st(1)
80485f0: da e9 fucomppи за счёт сравнения на стеке FPU при более широкой точности — получается данный эффект.
В стандарте C возможность подобного определяется макросом FLT_EVAL_METHOD, но в этих тестах он был равен -1, что значит, что нет определённости на этапе компиляции. Для 64-битного режима с использованием SSE он равен 0.
В дотнете, как я понял, спросить это нет возможности.
Re: [StackOverflow] вопросы недели
Здравствуйте, Sinix, Вы писали:
S>1. Красивейший гейзенбаг:
Запощу для архива аналог (не в смысле гейзенбага, а воспроизведение ситуации, которая найдена при разборе) для C.
fpsetprec это для FreeBSD, для других платформ _controlfp и тому подобное. FP_PS ставит точность на single, ответ — 1. FP_PD (double), FP_PE (extended) приводит к ответу 0. Разумеется, компиляция должна быть с использованием FPU (умолчание для 32 бит), на SSE не повторяется. От уровня отладки не зависит, благодаря volatile.
В ассемблере получается
и за счёт сравнения на стеке FPU при более широкой точности — получается данный эффект.
В стандарте C возможность подобного определяется макросом FLT_EVAL_METHOD, но в этих тестах он был равен -1, что значит, что нет определённости на этапе компиляции. Для 64-битного режима с использованием SSE он равен 0.
В дотнете, как я понял, спросить это нет возможности.
S>1. Красивейший гейзенбаг:
Запощу для архива аналог (не в смысле гейзенбага, а воспроизведение ситуации, которая найдена при разборе) для C.
#include <stdio.h>
#include <ieeefp.h>
volatile float a, b, f1;
int main() {
fpsetprec(FP_PD);
a = 0.1f;
b = 0.2f;
f1 = a + b;
printf("%d\n", f1 == (a + b));
return 0;
}fpsetprec это для FreeBSD, для других платформ _controlfp и тому подобное. FP_PS ставит точность на single, ответ — 1. FP_PD (double), FP_PE (extended) приводит к ответу 0. Разумеется, компиляция должна быть с использованием FPU (умолчание для 32 бит), на SSE не повторяется. От уровня отладки не зависит, благодаря volatile.
В ассемблере получается
80485c8: d9 05 b8 98 04 08 flds a
80485ce: d9 05 c0 98 04 08 flds b
80485d4: de c1 faddp %st,%st(1)
80485d6: d9 1d bc 98 04 08 fstps f1
80485dc: d9 05 bc 98 04 08 flds f1
80485e2: d9 05 b8 98 04 08 flds a
80485e8: d9 05 c0 98 04 08 flds b
80485ee: de c1 faddp %st,%st(1)
80485f0: da e9 fucomppи за счёт сравнения на стеке FPU при более широкой точности — получается данный эффект.
В стандарте C возможность подобного определяется макросом FLT_EVAL_METHOD, но в этих тестах он был равен -1, что значит, что нет определённости на этапе компиляции. Для 64-битного режима с использованием SSE он равен 0.
В дотнете, как я понял, спросить это нет возможности.