Имеется код на C и C++

/*c.c*/
#include <stdio.h>

int main()
{
   double i;
   for (i=-0.4; i<=0.4; i+=0.1) printf("%.1f\n",i);
   return 0;
}

/*cpp.cpp*/
#include <iostream>
int main()
{
    for (double i=-0.4; i<=0.4; i+=0.1) 
        std::cout << i << std::endl;
    return 0;
}

 Консоль:
$ gcc c.c -o c
$ g++ cpp.cpp -o cpp
$ ./c
-0.4
-0.3
-0.2
-0.1
-0.0
0.1
0.2
0.3
0.4
$ ./cpp
-0.4
-0.3
-0.2
-0.1
-2.77556e-17
0.1
0.2
0.3
0.4

я понимаю, что чистого нуля тут не получается из за представления числа 0.1 в двоичной системе. Но почему на C выводит 0, а на С++ нет? Различия в оптимизации или что? Кто может объяснить мне это?

2 (12.11.2010 18:36:47 отредактировано zhevak)

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

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

Хотите еще пример? Извольте! Имеем два языка -- C/C++ и C#. (В данном случае С и С++ в одной категории.)
имеем рабочий, но сомнительный код. (Сомнительный -- в том плане, что такое написание крайне не рекомендуется.)

int x;
int y;

x = 3;
y = x++ + ++x;

Вопрос: чему будет равно значение y?

Live Free or Die

3

если по теме.... то в printf задается форматирование..... замените на

std::cout <<std::fixed<< i << std::endl;

4 (12.11.2010 19:31:55 отредактировано zhevak)

напрягает не разное поведение программ, и даже не обстоятельство не знания топикстартером потоковых форматов, а то, что при очень "хорошем" типе double такая большая ошибка округления. Я бы еще понял, если б это был float, но double ... ac

хех. Понеслась!
1. Допишите модификатор volatile в объявлении переменной i. Таким образом компилятор не будет размещать переменную в регистрах математического сопроцессора, а создаст ее (т.е. зарезервирует для нее место) в памяти.
2. Создайте еще одну переменную -- указатель на байт (unsigned char *), присвойте ей адрес переменной i с предварительной кастомизацией типа.
3. Переменная i занимает 8 байт. Выведите их в консоль. Сравните что у Вас лежит в памяти в случае с Си, а что в случае с Си++, когда i должна быть равна нулю.

Live Free or Die

5 (14.11.2010 17:11:18 отредактировано Hvzh)

zhevak,
Вопрос: чему будет равно значение y?
10

6

zhevak,

zhevak пишет:

int x;
int y;

x = 3;
y = x++ + ++x;

вообще-то, как модератор я Вас забанить за такой код обязан.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)