Перебор чисел в плавающем с AVR-C - PullRequest
0 голосов
/ 09 ноября 2019

В настоящее время я использую это для перебора цифр целого числа. Работает довольно хорошо, за исключением одного 0, что и следовало ожидать.

void hc595_number(unsigned int number) {    
    while(number) {
        hc595_digit(number % 10);
        number /= 10;
    }
}

Однако то, что я сейчас не могу сделать (потому что% не принимает число с плавающей точкой и целое число), является итерацией, так же, как и числа с плавающей точкой. Мне нужно также определить точку в плавающей точке и сделать что-то немного другое для следующей цифры вместо hc595_digit, как я могу сделать для обычных цифр.

Итак, в основном для 12.4Мне нужно было бы вызвать hc595_digit на 4, затем записать следующую вещь, являющуюся точкой, а затем для 2, вызвать другую функцию.

Какой самый простой способреализовать это в AVR-C

1 Ответ

3 голосов
/ 09 ноября 2019

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

Даже целые числа не сохраняются в виде десятичных цифр. Они представлены в двоичном виде. Когда вы используете % 10 и / 10, вы рассчитываете десятичное представление для них. (Если бы они были сохранены с десятичным представлением, C, вероятно, имел бы некоторый оператор для доступа цифр, своего рода оператор индекса, такой как x[3], для получения третьей цифры x. Вместо этого вы используете вычисления , например % 10, для вычисления цифр.)

Во многих реализациях C используется базовый 64-битный двоичный формат IEEE-754 для double. Предположим, что ваша реализация C делает, и вы выполняете x = 12.6;. Тогда значение x не равно 12.6, потому что 12.6 не может быть представлено в этом формате. Вместо этого 12.6 округляется до представимого значения. Если оно правильно округлено до ближайшего представимого значения, результат будет 12,5999999999999996447286321199499070644378662109375. Если вы правильно вычислите первую цифру после десятичной точки, вы получите 5, а не 6.

Можно написать код для получения этих цифр. В хорошей реализации на C проще всего использовать snprintf для форматирования числа. Можно также написать вычисления для вычисления этих цифр, и C имеет функции fmod, remainder, remquo и modf, которые служат целям, аналогичным оператору % для целых чисел. Однако умножение на 10 в двоичном формате с плавающей запятой проблематично, потому что умножение, как и большинство операций с плавающей запятой, дает результат, который является математическим результатом действительного числа, округленным до ближайшего представимого значения. Простое умножение на 10 попытается вычислить цифры, что приведет к ошибкам и даст неправильные результаты.

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

...