что подразумевается под «системой Most C, обеспечивающей логически бесконечные плавающие значения»? - PullRequest
3 голосов
/ 23 марта 2020

Изначально я объявил переменные x и y как тип int:

#include<stdio.h>   

     int main(){
        int x, y = 0 ;
        x = 1 / y;
        printf("%d", x);

        return 0;    
    }

Сбой программы (по понятным причинам).

Теперь я объявил переменные x и y как double:

#include<stdio.h>   

 int main(){
    double x, y = 0 ;
    x = 1 / y;
    printf("%d", x);

    return 0;    
}

Но вывод: 0. (почему?)

Затем я изменил% d на% f в printf:

#include<stdio.h>   

 int main(){
    double x, y = 0 ;
    x = 1 / y;
    printf("%f", x);

    return 0;    
}

Вывод: 1. # INF00

Я не понимаю, что здесь происходит.

Пожалуйста, объясните мне приведенные выше случаи.

Ответы [ 2 ]

5 голосов
/ 23 марта 2020

Большинство систем, с которыми вы, вероятно, столкнетесь, используют IEEE 754 представление для чисел с плавающей запятой. Это представление имеет способы хранения значений + бесконечность и -infinity.

Строго говоря, деление на 0 равно неопределенное поведение , реализации, использующие IEEE 754, расширяют язык, чтобы разрешить его для типов с плавающей запятой. В этом случае деление на 0 можно считать бесконечностью, поэтому ваша реализация позволяет это, и 1.#INF00 - это то, как MSV C печатает значение для бесконечности.

Кроме того, используя неверный спецификатор формата для печати как во втором примере, где вы используете %d для печати double, это неопределенное поведение. Спецификаторы формата должны соответствовать типу данных того, что передается.

1 голос
/ 23 марта 2020

В компьютере нет цифр. Мы строим компьютеры из физических частей, и мы используем физические свойства для хранения и манипулирования данными.

В различных местах компьютер имеет электрические c заряды, электрические c напряжения, магнитные c поля, или другие физические вещи, которые мы используем для представления данных. При этом мы выбираем какое-то физическое состояние и называем его «0», а другое - «1». Это просто удобные имена. Математические числа, такие как 0 и 1, являются абстрактными объектами - это понятия без физического существования. Числа 0 и 1. не существуют в компьютерах.

Мы объединяем эти физические состояния, часто в группы по восемь, 32 или 64, и затем помечаем их различными способами. Например, с восемью битами в состояниях, помеченных как 00100010, мы можем назвать это «34». Это все еще не число. Мы просто используем двоичную запись для числа 34, и эта двоичная запись дополнительно обозначает состояние частей машины.

Куски машины в состоянии 00100010 по своей сути не являются действительными числами 34. больше, чем банан или понятие красного.

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

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

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

Когда вы печатаете объект с плавающей точкой, который в качестве битового шаблона, представляющего бесконечность, с использованием printf("%f", x);, реализация C печатает строку, представляющую бесконечность. Для этого Microsoft выбрала строку «1. # INF00», что довольно уродливо. В некоторых других реализациях используется «inf», что немного лучше.

Когда вы пытаетесь напечатать объект с плавающей запятой, используя printf("%d", x);, поведение не определяется стандартом C, потому что * Преобразование 1021 * ожидает получения объекта int, но передаваемый вами x является объектом double. Передача неверного типа аргумента может привести к нарушению механизма передачи аргументов различными способами, поэтому вы не всегда получите ответы, которые имеют смысл, не зная, как работают внутренние компоненты программного обеспечения.

...