LINUX.ORG.RU

Число Пи в Си

 


0

4

Здравствуйте!

Константа Pi определена в файле math.h следующим образом:

cat /usr/include/math.h | grep M_PI
# define M_PI		3.14159265358979323846	/* pi */

Теперь я хочу вывести ее на экран:

printf("M_PI = %.25f\n",M_PI);

И получаю результат:

M_PI = 3.1415926535897931159979635

Уважаемые знатоки, внимание вопрос: почему значения не совпадают?

Deleted
Ответ на: комментарий от i-rinat

Я верю, что когда-нибудь до тебя дойдёт.

Теперь я понимаю царя. Типичный лор, рассуждения больше одного предложения не читают и пытаются что-то кому-то доказать. Что непонятного было в Число Пи в Си (комментарий) насчёт того, что __attribute__ генерит не ошибки, а предупреждения и отлавливает явно ошибочное перепутывания значений и указателей? Зачем вы меня с 35 летним стажем программирования на C пытаетесь учить моими же примерами?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Зачем вы меня с 35 летним стажем программирования на C пытаетесь учить моими же примерами?

Видимо, 35 лет стажа убивают способность читать. И без подсказок уже не дойдёт. Я уже так намекал на типы, и сяк. Прямо несколько раз сказал. И всё без толку.

Помнишь, ты писал следующее?

Переменное число аргументов тут не при чём.

Ну так вот, при чём. Аргументы типа float, передающиеся в функцию с переменным числом аргуметов (если они входят в те самые ..., конечно) преобразуются в double передающей стороной. Это так язык Си устроен.

Что непонятного было в Число Пи в Си (комментарий) насчёт того, что __attribute__ генерит не ошибки

Это вообще-то достаточно очевидная фича. Но вот дальше там явный бред написан:

А использование %f — это не дань какой-то там экономии, а просто демострация, что для результата такая точность достаточна, например. если сами вычисления были не выше точности, чем float, используя скажем исходные данные в float-ах (вот тут уже экономия).

Э-эм, что? Что за магическое мышление?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Это так язык Си устроен.

Это ваше магическое знание, как ни смешно, точно попадающее под это определение: вы по внешнему проявлению делаете общие заключения. Любые функции передают в стек float как double. Так же как char в int. Потому что этот стандарт родился ещё до того, как появился синтаксис эллипса (...) и декларация аргументов у функций.

Э-эм, что?

Мне пофиг, что вы не умеете парсить.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Это ваше магическое знание, как ни смешно, точно попадающее под это определение: вы по внешнему проявлению делаете общие заключения.

Я могу ссылку на пункт в N1570 предоставить. А ты?

Любые функции передают в стек float как double.

Ссылку на пункт в публично доступном драфте стандарта, пожалуйста.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я могу ссылку на пункт в N1570 предоставить. А ты?

И что, там написано, что float в double попадает только для эллипсов?

Ссылку на пункт в публично доступном драфте стандарта, пожалуйста.

Ну то есть как обычно — в рассуждения даже не вникли. Как я могу дать вам ссылку на K&R с эллипом, если при них его не было?

vodz ★★★★★
()
Ответ на: комментарий от vodz

И что, там написано, что float в double попадает только для эллипсов?

Ты текст парсить не умеешь? Не пытайся приписать мне утверждения, которые я не писал. Давай лучше обсудим вот это твоё утверждение:

Любые функции передают в стек float как double.

Для начала, определимся с тем, что ты хотел этим сказать.

Ну то есть как обычно — в рассуждения даже не вникли.

Нет смысла вникать в рассуждения, если изначальное утверждение ошибочно. Зачем вникать в «объяснения» ошибочного суждения? Проще сразу к сути перейти.

Как я могу дать вам ссылку на K&R с эллипом, если при них его не было?

Ссылку на пункт в стандарте языка Си.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Не пытайся приписать мне утверждения, которые я не писал

А вот это кто писал: Число Пи в Си (комментарий) ?

Нет смысла вникать в рассуждения,

Дооо.

//#include <math.h>
# define M_PI           3.14159265358979323846  /* pi */

int main(void)
{
        printf("%f %f\n", sin(M_PI), sin((float)M_PI));
        return 0;
}
$ ./a.out 
0.000000 -0.000000

А теперь покажите в библиотеки наличие функции sin(...). И да, оно именно это и хотело сделать, ибо выдало предупреждения, что builting хочет double, а вы передаете как неизвестные аргументы.

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

Проще сразу к сути перейти.

Получилось ненаглядно. Но вот так будет лучше:

#include <stdio.h>
//#include <math.h>
# define M_PI           3.14159265358979323846  /* pi */

#ifdef VAR2
double sin(double);
#else
double sin(float);
#endif

int main(void)
{
        printf("%.10f %.10f\n", sin(M_PI), sin((float)M_PI));
        return 0;
}
$ cc xsin.c -lm; ./a.out
0.0000000000 0.0000000000
$ cc -DVAR2 xsin.c -lm; ./a.out
0.0000000000 -0.0000000874
То есть когда мы объявляем sim(float x), то никаких преобразований во float при sin((float)M_PI)) не делается, так как считается, что это преобразование сделает сама функция, потому и получаем чистый 0 в обоих случаях как-будто передали double, то есть ЧТД: float в любой функции передается как double.

Ссылку на пункт в стандарте языка Си.

Это можно поискать, но это труд, он должен быть оплачен. Тем специалисты и отличаются, что не лезут по каждому чиху в стандарт, а юзают свои знания, только это и позволяет им быть спецами — зарабатывать на этом.

vodz ★★★★★
()
Ответ на: комментарий от vodz

А вот это кто писал: Число Пи в Си (комментарий) ?

Это писал я. Теперь найди, где там написано «что float в double попадает только для эллипсов». (Кстати, можешь не стараться, там этого нет.)

Дооо.

35 лет стажа, а так позоришься. Не стыдно? Проблема не в том, что ты что-то можешь не знать. Проблема в том, что ты не допускаешь мысли о том, что ты можешь что-то не знать. Это очень пагубно для программиста.

А теперь покажите в библиотеки наличие функции sin(...). И да, оно именно это и хотело сделать, ибо выдало предупреждения, что builting хочет double, а вы передаете как неизвестные аргументы.

Ты обрезал double константу в float. Потом передал в функцию, где параметр имеет тип double. В таком случае параметр будет неявно преобразован в double.

6.5.2.2 Function calls

<...>

6
If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.

7
If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

Я выделил важные части. Есть implicit conversion. Ты пишешь про него, и думаешь, что это единственный механизм. Но есть ещё default argument promotion. И такое ощущение, что про него ты слышишь впервые.

Если параметр функции — double, а ты передаёшь туда int, char, float или что ещё, что может быть подвергнуто implicit conversion, оно произойдёт. А есть default argument promotions, которые работают, либо если у функции нет прототипа, либо если в прототипе нет типов под эти аргументы. Char преобразуется в int, float — в double.

И ещё раз возвращаемся к твоему утверждению: «Любые функции передают в стек float как double». Это утверждение ошибочно.

i-rinat ★★★★★
()
Ответ на: комментарий от vodz

Это можно поискать, но это труд, он должен быть оплачен. Тем специалисты и отличаются, что не лезут по каждому чиху в стандарт, а юзают свои знания, только это и позволяет им быть спецами — зарабатывать на этом.

Ой, не позорься. Открыть документ, пролистать оглавление и открыть нужный пункт. Ты на написание ответа больше времени потратил, чем на поиск ушло бы.

Да и оплачивать специалиста с ложными знаниями основного рабочего инструмента — не очень разумная трата денег.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Кстати, можешь не стараться, там этого нет.

Конечно в исходном тексте этого нет, так как на это и было добавлено, что это эллипс не при чём. Вы уж либо крестик либо трусы наденьте.

И ещё раз возвращаемся к твоему утверждению: «Любые функции передают в стек float как double». Это утверждение ошибочно.

Да, предыдущий пример был ненагляден и я уже написал другой.

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

Ой, не позорься.

Ну то есть найти опровержение на моё высказывание вы не можете, пример скипнули даже не читая, но зуд не даёт не нахамить и потом еще утверждаете, что опонент позорится?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Ну то есть найти опровержение на моё высказывание вы не можете

Про sin() и разные типы параметров в прототипе? Попробуй вместо M_PI передавать M_PI/2, вот и будет тебе опровержение.

i-rinat ★★★★★
()
Ответ на: комментарий от vodz

Конечно в исходном тексте этого нет, так как на это и было добавлено, что это эллипс не при чём. Вы уж либо крестик либо трусы наденьте.

Если хочешь что-то добавить, пиши выражения от своего имени, а не пытайся приписать их другим.

И ещё раз возвращаемся к твоему утверждению: «Любые функции передают в стек float как double». Это утверждение ошибочно.

Да, предыдущий пример был ненагляден и я уже написал другой.

А ты вообще читаешь то, что цитируешь? Твой ответ вообще не в тему.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Про sin() и разные типы параметров в прототипе?

Да.

Попробуй вместо M_PI передавать M_PI/2, вот и будет тебе опровержение.

Ну попробовал. На писюке — 0, на HP-UX B.11.31 U ia64 — 1.00000000000000000000 0.99999999999999900080 во втором варианте (с %.20f для точности). Разница в том, что sin() в gcc — builtin, на чпуксе никакого дополнительного интелекта нет и делает то что в доказательстве написано.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от vodz

Ну попробовал.

Тебя не смутило, что вообще-то около единицы должно было получиться?

Может, вот этот вариант на какие-то мысли наведёт?

#include <stdio.h>

double sin(float);

int main(void) {
  for (float a = 0; a < 1; a += 0.125) {
    printf("%.10f\n", sin(a));
  }
}

Как думаешь, что он должен напечатать? А что печатает?

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от Deleted

Вывод зависит от количества знаков после запятой
Странно

Ничего странного. Там простое округление :)

KRoN73 ★★★★★
()
Ответ на: комментарий от utf8nowhere

не там прикол в том, что эту универсальную газовую постоянную раз в несколько лет экспериментально уточняют.

это калория имеет три разных значения в зависимости от «контекста»

grem ★★★★★
()
Ответ на: комментарий от Deleted

прочитай уже наконец про представление чисел с плавающей точкой или подожди пока вам об этом на первом курсе расскажут, если лень

grem ★★★★★
()
Ответ на: комментарий от i-rinat

Тебя не смутило, что вообще-то около единицы должно было получиться?

Оно и получилось на не на x86-gnu-компиляторе, что же вы так креативно цитируете. То есть для корректного теста делаем my_sin(double x) в main() и my_sin(float x) в отдельной библиотеке. В результате имеем реально double x без конвертации из float, потому результат очень точно 1, и всё равно double но с конвертацией из float с потеренной точностью с результатом 0.(9)8. На x86-gnu-компиляторе на стеке так же double в обоих случаях, но выбирается половина, которая 0, а если поменять типы местами, то в не-x86 оба результата 0.(9), а на x86 в стеке мусор: -0.74464254474893964986 -0.59424287339866921354, то есть работа идёт с недоформированным double.

Я кажется понял, в чём ваша проблема. Вы потому и полезли в стандарт, что этого точно не знали/забыли и пытаетесь там отыскать эту магию, без понимания, почему это происходит и как так получилось с преобразованием по умолчанию, но то что там такая магия есть вы смутно помните. Но проблема в стандарте в том, что там глупо описывать историю и причины появления такого поведения. С обязательным преобразованием char в int я уже тут причину описал, а с float получилось прикольнее. Дело в том, что (со)процессоры с float как правило в большинстве архитектур не работают, они даже эти упаковки<->распаковки float<->double бывает делают с помощью обычного процессора, а не самим сопроцессором. Но для такой распаковки требуется зачастую память. Потому и пошли по пути передачи всегда double, чтобы уже была память с формированным числом для произведения с ними вычислений.

Как думаешь, что он должен напечатать?

Что за странное желание удивить детскими примерами?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Оно и получилось на не на x86-gnu-компиляторе, что же вы так креативно цитируете.

Почему тогда оно не получилось на «x86-gnu-компиляторе»? Цитирую я важную часть.

То есть для корректного теста делаем my_sin(double x) в main() и my_sin(float x) в отдельной библиотеке. В результате имеем реально double x без конвертации из float, потому результат очень точно 1, и всё равно double но с конвертацией из float с потеренной точностью с результатом 0.(9)8.

Сделай этот тест в реальности, а не только в воображении.

0.(9)8

Так писать — глупо. В математике принято в скобках указывать бесконечно повторяющуюся часть. Не может быть там цифр после.

На x86-gnu-компиляторе на стеке так же double в обоих случаях, но выбирается половина, которая 0

Во-первых, откуда взялось это «выбирается половина»? Во-вторых, какая половина от числа Пи равна нулю? Первая или вторая?

то есть работа идёт с недоформированным double.

Ты же раньше писал, что всегда передаётся double. Откуда «недоформированный» double?

Я кажется понял, в чём ваша проблема. Вы потому и полезли в стандарт, что этого точно не знали/забыли и пытаетесь там отыскать эту магию, без понимания, почему это происходит и как так получилось с преобразованием по умолчанию, но то что там такая магия есть вы смутно помните. Но проблема в стандарте в том, что там глупо описывать историю и причины появления такого поведения.

Моя проблема в том, что я в спорных случаях лезу в описание языка?

Дело в том, что (со)процессоры с float как правило в большинстве архитектур не работают, они даже эти упаковки<->распаковки float<->double бывает делают с помощью обычного процессора, а не самим сопроцессором. Но для такой распаковки требуется зачастую память. Потому и пошли по пути передачи всегда double, чтобы уже была память с формированным числом для произведения с ними вычислений.

Бред какой.

Что за странное желание удивить детскими примерами?

Раз детский пример, должно же быть просто, да? Почему боишься тогда?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Сделай этот тест в реальности, а не только в воображении.

То есть по вашему эти все 0.99999999999999900080, -0.74464254474893964986 и -0.59424287339866921354 я получил в воображении?

Во-вторых, какая половина от числа Пи равна нулю? Первая или вторая?

Тю, даже этого не знаете. Для архитектуры sizeof float=4, sizeof double=8 половина с нулём определяется endian архитектуры.

Почему тогда оно не получилось на «x86-gnu-компиляторе»?

Потому что обнулять ли вторую половину или оставлять там мусор потому что мы явно определили, что работаем с одинарной точностью определяется компилятором и стандарта на это нет.

Раз детский пример, должно же быть просто, да? Почему боишься тогда?

Я о людях всегда лучшего мнения и предлагаю разбирать примеры по теме. Вот вам для писюка:

$ cat xlib.c
#include <math.h>
#include <stdio.h>
#include <string.h>

double dirty_sin(unsigned int start, double pi, double d2, unsigned int end)
{
        float fpi, f2;
        printf("start=%x pi=%f d2=%f end=%x\n", start, pi, d2, end);
        memcpy(&fpi, &pi, sizeof(float));
        memcpy(&f2, &d2, sizeof(float));
        printf("start=%x fpi=%f f2=%f end=%x\n", start, fpi, f2, end);
        return sin(fpi/f2);
}
$ cat dirty.c
#include <stdio.h>
#include <math.h>

double dirty_sin(unsigned int start, float pi, float f2, unsigned int end);

int main(void)
{
        printf("sizeof unsigned int=%u, sizeof float=%u, sizeof double=%u\n",
                sizeof(unsigned int), sizeof (float), sizeof (double));
        printf("%.20f\n", dirty_sin(0xbeefdead, M_PI, 2, 0xdeadbeef));
        return 0;
}
$ cc dirty.c xlib.c -lm; ./a.out
sizeof unsigned int=4, sizeof float=4, sizeof double=8
start=beefdead pi=0.000000 d2=0.000000 end=deadbeef
start=beefdead fpi=3.141593 f2=2.000000 end=deadbeef
0.99999999999999900080
Как видим, в стеке независимо от декларации float помещаются float-ы со смещением double с обнуленной частью для gcc 4.8.2 (и не обнулённой для gcc 4.2.3).

Бред какой.

Ну да, я всё время забываю, что у вас с парсером большие проблемы.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Как видим, в стеке независимо от декларации float помещаются float-ы со смещением double с обнуленной частью для gcc 4.8.2 (и не обнулённой для gcc 4.2.3).

Я не могу понять, ты идиот или просто прикидываешься?

В x86-64 ABI числа с плавающей точкой передаются в отдельных регистрах SSE. При передаче ты заполняешь первые 32 бита. Остальная часть регистра обычно будет содержать мусор, но при старте там будут нули. Вызываемая функция интерпретирует это как double. Видишь, у тебя код печатает pi=0.000000, хотя ты передавал M_PI? Там на самом деле не ноль, а просто маленькое число получилось (5.3286462644e-315), которого не видно при печати числа с фиксированной позицией запятой. Там нет преобразования в double, как ты пытаешься показать. Данные записываются «как есть», а потом читаются «как есть».

Более того, так как целочисленные параметры передаются в регистрах общего назначения, а параметры с плавающей точкой — в SSE регистрах, можно в некоторых пределах поменять порядок параметров, и работать будет точно так же. Попробуй, например, в xlib.c поменять так:

double dirty_sin(unsigned int start, unsigned int end, double pi, double d2)

В i386 ABI параметры с плавающей точкой пушатся в стек. И там будет месиво, когда вызываемая функция попытается прочитать из стека не то, что она там ожидает.

Потому что обнулять ли вторую половину или оставлять там мусор потому что мы явно определили, что работаем с одинарной точностью определяется компилятором и стандарта на это нет.

Это просто бред. Отсюда можно попытаться вычленить разумные утверждения, но всё это вместе связано в бредовое восприятие мира. Причём со святой уверенностью в своей правоте. Что ж, видимо, 35 лет программирования не проходят бесследно.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Я не могу понять, ты идиот или просто прикидываешься?

Я не могу понять, почему вы всё время нарываетесь на ПНХ?

у тебя код печатает pi=0.000000, хотя ты передавал M_PI? Там на самом деле не ноль, а просто маленькое число получилось (5.3286462644e-315)

Да неужели? С чего вы взяли, что я не знаю, что получается на писюке если имеется «double» с обнуленной частью? Какое это отношение имеет эта «на самом деле» к обсуждаемому вопросу? Вы вообще кроме писюка что-нибудь знаете? С чего вы взяли, что при этом вообще везде и всюду должно получаться какое-либо реальное число?

Данные записываются «как есть», а потом читаются «как есть».

Я вам уже давал результаты, где не SSE, в параметрах функции правильные double и, если указано, то с float-точностью. Поставил там gcc-ia64, получил ровно тот же результат.

Что ж, видимо, 35 лет программирования не проходят бесследно.

Дык. Я именно что застал времена С K&R, когда не было в синтаксисе C ни деклараций аргументов функций, ни эллипса, потому никакого другого поведения кроме как сейчас работает с эллипсом и не было, все функции получали параметры через стек и с преобразованием по дефолту. Сейчас на C оказывает влияние плюсы, теперь работа с недекларированными функциями ничего не гарантирует вообще, а передача аргументов через регистры вообще появилось как расширения коммерческих компиляторов и только потом пришло в gcc как __attribute__(regparm) но так и не попав в стандарт.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Я именно что застал времена С K&R

Ты и до сих пор транслируешь понятия оттуда. Почитал бы хоть ANSI C для приличия, чтоб не методом тыка язык изучать.

anonymous
()
Ответ на: комментарий от vodz

Я не могу понять, почему вы всё время нарываетесь на ПНХ?

Это просто ты начинаешь осознавать свою некомпетентность в вопросе, и у тебя начинается бурление.

Да неужели? С чего вы взяли, что я не знаю, что получается на писюке если имеется «double» с обнуленной частью? Какое это отношение имеет эта «на самом деле» к обсуждаемому вопросу?

Да прямое. Сначала ты писал, что всегда передают double. Теперь оказывается, что там обнулённая часть, и ты об этом знаешь. Два утверждения друг другу противоречат.

Вы вообще кроме писюка что-нибудь знаете?

Нет, не знаю. А ты пытаешься знакомством с очередной платформой заменить знание языка программирования? У тебя есть шелл-доступ на ia64 и теперь ты самый умный? Сейчас такое можно легко организовать с помощью qemu. (Я недавно проверял сборку софта на s390x. Это что-то, чем нужно гордиться, что ли?)

С чего вы взяли, что при этом вообще везде и всюду должно получаться какое-либо реальное число?

Ничего подобного я не утверждал. Там легко может получиться что угодно. Это зависит от конкретных чисел.

Я вам уже давал результаты, где не SSE, в параметрах функции правильные double и, если указано, то с float-точностью. Поставил там gcc-ia64, получил ровно тот же результат.

Ну, во-первых, ты не осилил даже встроенный sin() отключить. О какой корректности твоих проверок вообще может идти речь? Во-вторых, ты же даже не смотрел, что за код генерируется компилятором.

Дык. Я именно что застал времена С K&R

Ты в тех временах и остался. Зачем ты пытаешься лезть с советами в настоящем времени? Сиди и ковыряйся с древними компиляторами. Современный GCC уже не поддерживает тот язык. Он поддерживает Си, описанный в современных стандартах.

теперь работа с недекларированными функциями ничего не гарантирует вообще

Это утверждение ложно. Читай стандарт, там написано, как это происходит.

передача аргументов через регистры вообще появилось как расширения коммерческих компиляторов и только потом пришло в gcc как __attribute__(regparm) но так и не попав в стандарт.

Это определяется ABI платформы, и в современном линуксе стандартизировано. Есть документ, в котором описано, как происходит вызов функции, как параметры размещаются в регистрах и памяти. К стандарту языка Си это не имеет отношения, поэтому в нём не декларируется. Разные платформы могут иметь свои соглашения о вызовах.

Твои попытки давить авторитетом «35-летнего стажа» выглядят смешно. Особенно смешно то, что ты ещё и чушь при этом пишешь.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

что всегда передают double. Теперь оказывается, что там обнулённая часть, и ты об этом знаешь. Два утверждения друг другу противоречат.

А под обнуленную часть память не надо?

А ты пытаешься знакомством с очередной платформой заменить знание языка программирования?

Типичный передерг. Я лишь сказал, что ваша «на самом деле там маленькое число» — чушь при рассмотрении с общих позиций.

ты не осилил даже встроенный sin() отключить

А что, это отключение уже в стандарте языка? Зачем мне его отключать, если смотрится его конечный результат, ну а в последнем варианте он вообще остался только данью преемственности тестов.

Это утверждение ложно. Читай стандарт, там написано, как это происходит.

Это утверждение абсолютная истина по определению недекларированности: функция в одном модуле с regparm несовместима с её вызовом при отсутствии декларации regparm (cdecl, frame-pointer, etc). Стандарты лишь говорят об одном из поведений, ясен пень, что если этому поведению следовать, то будет это поведение и происходить.

vodz ★★★★★
()
Ответ на: комментарий от vodz

А под обнуленную часть память не надо?

Если они передаются как double, зачем память под обнулённую часть? Её же нет. Всё место занято числом double. У тебя какая-то каша в голове.

Типичный передерг. Я лишь сказал, что ваша «на самом деле там маленькое число» — чушь при рассмотрении с общих позиций.

Ты цепляешься к словам. Ну хорошо, с общих позиций там undefined behavior. Так лучше?

А что, это отключение уже в стандарте языка? Зачем мне его отключать, если смотрится его конечный результат, ну а в последнем варианте он вообще остался только данью преемственности тестов.

Опять каша в голове. Ты компилируешь компилятором, а не стандартном языка. Очевидно, отключение есть в опциях компилятора. Не осилил документацию на рабочий инструмент? Тем хуже для тебя.

Это утверждение абсолютная истина по определению недекларированности

Ты заявил, цитирую:

теперь работа с недекларированными функциями ничего не гарантирует вообще

Повторяю. Это утверждение — ложное. В стандарте языка явно указано, как компилятору следует трактовать недекларированные функции. Хватит представлять свои фантазии как некую истину. Читай стандарт.

Это утверждение абсолютная истина по определению недекларированности

Мда... А определение, конечно же, придумал ты сам.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Если они передаются как double, зачем память под обнулённую часть? Её же нет. Всё место занято числом double.

Вы рассматриваете что? Эллипс? Так там и делается настоящий double без нулей. Если мы декларируем float, значить у нас значение в половинке double. Что будет передано на стек/регистры, а именно либо передача double независимо от декларации, либо только float (ему повезло, он достаточно выровнен и нативный по размеру, в отличии от char), либо float с половинкой с нулями либо мусором определяется не стандартом языка, а реализацией компилятора.

У тебя какая-то каша в голове.

Так ведь взаимно. Вы со своей магией вечно путаете стандарт языка и ABI, и почему-то не видите этой каши.

Повторяю. Это утверждение — ложное.

Повторяю. Масло-масленное не может быть истинным по определению тавтологии. Ибо обратное, когда в одном месте задекларировали float, а в другом - double мы тут и рассматриваем.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Вы рассматриваете что? Эллипс? Так там и делается настоящий double без нулей.

Число Пи в Си (комментарий)

Ты пытаешься мне доказать то, что я и писал?

Если мы декларируем float, значить у нас значение в половинке double. Что будет передано на стек/регистры, а именно либо передача double независимо от декларации, либо только float (ему повезло, он достаточно выровнен и нативный по размеру, в отличии от char), либо float с половинкой с нулями либо мусором определяется не стандартом языка, а реализацией компилятора.

Тут ты съехал в софистику, забыв вообще, что пытался сказать.

Так ведь взаимно. Вы со своей магией вечно путаете стандарт языка и ABI, и почему-то не видите этой каши.

Тот факт, что я где-то упоминаю стандарт языка, а где-то — стандарт ABI, не означает, что я их путаю. Наоборот, я знаю, что определяется стандартом, а что — ABI. Ты же не видишь разницы, и это печально.

Повторяю. Масло-масленное не может быть истинным по определению тавтологии. Ибо обратное, когда в одном месте задекларировали float, а в другом - double мы тут и рассматриваем.

Софистика.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ты пытаешься мне доказать то, что я и писал?

Мне пришлось сделать скидку на ваш парсер, и напомнить, что с преобразованием при эллипсе я с вами никогда не спорил.

забыв вообще, что пытался сказать

Это ваши проблемы. Вот напоминаю:

Наоборот, я знаю, что определяется стандартом, а что — ABI.

Вы рьяно вступили в бой, пытаясь доказать, что в стандарте языка точно где-то указано, что передаётся и в других случаях, а не при эллипсе. Но мы так и не дождались.

Ты же не видишь разницы, и это печально.

Это типичный детский сад «сам дурак».

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вы рьяно вступили в бой, пытаясь доказать, что в стандарте языка точно где-то указано, что передаётся и в других случаях, а не при эллипсе. Но мы так и не дождались.

Где ссылка на сообщение, в котором я это доказываю?

Это типичный детский сад «сам дурак».

Ты текст стандарта открывал хотя бы за время этого обсуждения?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ты текст стандарта открывал хотя бы за время этого обсуждения?

Я вам дал два результата с разным поведением и понял, что этого момента в стандарте не найду и надеялся на вас. Но не судьба.

Если вы не поняли, с утверждением, что всегда передаётся double, я уже посыпал голову пеплом, теперь оказывается и так делать можно. Раньше так не делали и совершенно понятно почему и приводить те рассуждения повторно я не буду.

Зато вспомнил новое по поводу «декларированности». В конце 90-х, когда мода на regparm была в тренде, что позволяло на i386 получить одновременно и ускорение и уменьшение размера кода я так и не смог победить декларацию указателя на фукнцию с аргументами через регистры. Как только не извращался с typedef-ами и скобочками, оно молча игнорировало и передавало параметры через стек. Наверное я поймал глюк компилятора. В инете ни одного такого примера реализации простой и нужной идеи не нашел.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Что-то я не вижу ссылку на сообщения, где я якобы «рьяно вступили в бой, пытаясь доказать, что в стандарте языка точно где-то указано, что передаётся и в других случаях, а не при эллипсе. Но мы так и не дождались.»

Сомневаюсь, что я писал что-то подобное, потому что вполне очевидно, что в стандарте этого не будет. Конкретная реализация компилятора может не следовать соглашениям ABI платформы, и вообще передавать числа с плавающей точкой, преобразуя их в строковое представление, например. Если потом вызываемая функция поймёт это представление, этого достаточно для соответствия стандарту. В стандарте упоминается default promotion, где передающая сторона должна преобразовать float в double и передать его в том же виде, в каком передаётся double. Default promotions выполняются не всегда, а только во вполне определённых случаях — когда нет информации об ожидаемом типе. Это происходит, когда аргумент является одним из тех неуказанных в функции, принимающей произвольное число аргументов. Это либо пустые скобочки, либо многоточие, либо просто отсутствие прототипа функции вообще, что эквивалентно пустым скобочкам.

Я вам дал два результата с разным поведением и понял, что этого момента в стандарте не найду и надеялся на вас. Но не судьба.

В первый раз вижу это утверждение.

Если интересует, что стандарт говорит на тему поведения в случае несовместимых прототипов функций, там всё просто: undefined behavior. Это не implementation-defined, а именно undefined.

Если вы не поняли, с утверждением, что всегда передаётся double, я уже посыпал голову пеплом, теперь оказывается и так делать можно.

В первый раз вижу это утверждение. Сомневаюсь, что кто-либо мог понять это из твоих предыдущих сообщений. Там была только надменность.

Зато вспомнил новое по поводу «декларированности».

Вкратце, если функция не была декларирована перед вызовом, считается, что она int func(). C пустыми скобками, то есть принимает любое число параметров любых типов. К аргументам применяется default argument promotion.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Если интересует, что стандарт говорит на тему поведения в случае несовместимых прототипов функций, там всё просто: undefined behavior. Это не implementation-defined, а именно undefined.

Два дня хая, а оказывается как об стенку горох. Несовместимые декларации мной сделаны не для для того чтобы сломать японскую бензопилу (если вы помните тот анекдот), а для того, чтобы увидеть, что мы получим на самом деле другой тип в не зависимости от явной декларации не этого типа. Что можно увидеть при этом в стандарте для явно «хакерского» приёмчика? Я так думаю. что там даже ваш undefined для этих конкретных условий даже не рассматривается. Почему именно так: в виде декларации float при вызове и double при реализации функции  — рассказано почти в каждом сообщении. А посему:

Вкратце, если функция не была декларирована перед вызовом, считается, что она int func().

тред надо закрывать. Мне не интересно дальше распинаться перед человеком, который просто пропускает тонкости обсуждения мимо ушей, заявляя что что-то там впервые слышит, тыкает в стандарты, а потом оказывается, что он имел в виду тривиальщину, никак не имеющей отношения к обсуждаемой проблеме.

vodz ★★★★★
()
Ответ на: комментарий от vodz

тред надо закрывать. Мне не интересно дальше распинаться перед человеком, который просто пропускает тонкости обсуждения мимо ушей, заявляя что что-то там впервые слышит, тыкает в стандарты, а потом оказывается, что он имел в виду тривиальщину, никак не имеющей отношения к обсуждаемой проблеме.

Напомню, что я сказал, что при передаче float в printf он преобразуется в double, потому что так происходит при передаче в функции с переменным числом аргументов. Ты заявил, что переменное число аргументов тут не при чём. (Число Пи в Си (комментарий))

Какие тонкости обсуждения? Ты просто написал чушь, подкреплённую лишь твоим воображением, а потом надменно пытался её доказывать, приводя примеры, результаты которых сам объяснить в не в состоянии.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

число аргументов тут не при чём. Какие тонкости обсуждения?

Может быть в том, чтобы не врать а парсить? Напомню, я был убежден, что это конвертация производится всегда, а не только при эллипсе потому что ... далее по тексту.

приводя примеры, результаты которых сам объяснить в не в состоянии.

ЧТД. Вы можете только хамить и врать при никудышном парсере. Ну вот вам в вашем же стиле, чтобы было понятно: Вы даже не в состоянии вникнуть в результат, полученный на архитектуре, где производится именно так как было заявлено см выше, по старинке, а начали типичный лор: «хвастовство доступа к архитектуре», «воображение», «надменность» и так и продолжаете.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Может быть в том, чтобы не врать а парсить?

О том, что ты понимаешь, что был не прав, ты написал только сегодня. Вчера ты упорно отказывался читать даже цитаты из стандарта, которые я сюда писал, не то, что бы самому пойти почитать.

Приведи ссылку на своё сообщение, которое нужно было «распарсить». Посмотрим, может кто другой сможет «распарсить»? Я вот не осилил «распарсить». Видимо, нужно уметь мысли читать? Или libastral обновить? :-D

ЧТД. Вы можете только хамить и врать при никудышном парсере. Ну вот вам в вашем же стиле, чтобы было понятно: Вы даже не в состоянии вникнуть в результат, полученный на архитектуре, где производится именно так как было заявлено см выше, по старинке

Что забавно, так это то, что ты не понимаешь, что там происходит. Ну вот совсем.

В IA64 ABI (ссылка) в пункте 5.3 перечислены доступные регистры для чисел с плавающей точкой. Там явно не написано, но регистры имеют ширину в 82 бита. Примерно как в x87, но экспонента на два бита шире. При загрузке данных в регистр они расширяются, как это было в x87. Дальше, в пункте 8.5 написано, что первые восемь параметров функции передаются в регистрах. Целочисленные — в регистрах общего назначения, параметры с плавающей точкой — в регистрах для чисел с плавающей точкой, начиная с f8.

В твоих примерах нет функций с более чем восемью параметрами, поэтому все они передаются через регистры. Именно поэтому у тебя твои кривые (UB) примеры работают, а не потому, что в «стек записывается». До использования стека там просто дело не доходит.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

В твоих примерах нет функций с более чем восемью параметрами

Вам сколько в граммах надо? Проверил с 9-ю, ничего не изменилось.

Именно поэтому

Что за чушь я только что прочитал? А при эллипсе 80/82 бита значит юзается? Вы в самом деле не понимаете, что это не имеет значение?

у тебя твои кривые (UB) примеры работают

Ну я же говорю — эталонный лор: ни за что, никогда и нипочём не соглашаться. А уж закончить тред не последним...

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вам сколько в граммах надо? Проверил с 9-ю, ничего не изменилось.

А теперь прочитай внимательно те участки документа об ABI.

Что за чушь я только что прочитал? А при эллипсе 80/82 бита значит юзается?

В Itanium регистры для чисел с плавающей точкой — скалярные. При загрузке из памяти число растягивается в 82-битное представление. Так же, как в x87 FPU числа при загрузке из памяти растягивались в 80-битное представление. Существуют разные инструкции для загрузки float и double. (Забавно, что я это объясняю человеку, который тут пытался хвастаться знанием других платформ.)

Вы в самом деле не понимаете, что это не имеет значение?

Имеет. Потому что при передаче параметра с плавающей точкой нет способа накосячить с размером данных в памяти на стеке. Просто потому что данные не передаются через стек.

Ну я же говорю — эталонный лор: ни за что, никогда и нипочём не соглашаться. А уж закончить тред не последним...

Я не понимаю, почему нужно соглашаться с откровенно некорректными суждениями. И ты сам боишься не оставить последнее сообщение. :-D Вот это у тебя реально поведение детское.

Я бы рекомендовал тебе больше сюда не писать. И вообще в треды по тематике не лезть, пока матчасть не подучишь. Ты просто с каждым сообщением себя глубже и глубже закапываешь.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

А теперь прочитай внимательно те участки документа об ABI.

Как это связано с вашим предложением проверить на большим чем 8 аргументами? Нет, как связано я, конечно знаю, и потому предыдущий коммент закончил троеточием. Но теперь придётся продолжить: если фокус не удался, то надо генерировать дальше совсем уже абсолютную чушь всё с нарастающим хамством, в надежде, что на впечатлительных подействует.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Ну мы просто каждый день видим таких любителей ub свято уверенных в собственной правоте и непогрешимости, но при этом не способных указать на какие-либо факты или документацию (там вроде была попытка съехать что аби это не си, так вот не катит такое).

anonymous
()
Ответ на: комментарий от anonymous

Ну мы просто каждый день видим таких любителей ub свято уверенных в собственной правоте и непогрешимости

Безусловно, это печальное зрелище. Вот только как это относится к спецальным грязным приёмчикам, зависимым от архитектуры с проверкой и скурпулёзным разбирательством этого UB для чего и были написаны и даже о сюрпрайз с наименованием dirty к вышеуказанному спору?

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Маааам! Сматри я тралю Двач ЛОР!

Молодец, главное, что ты последний запостил!

shkolnick-kun ★★★★★
()
11 февраля 2019 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.