Разноформатное > Курилка
Программисты есть на форуме? Простая задачка с заковыкой.
voidmain:
Ахтунг! Язык демонофф! Многа букаFFh!
Возможны крах системы, потеря данных и красные глаза... В общем, я предупредил!Поехали!
Дано число с плавающей точкой(от 0 до 999.9999):
--- Код: ---float f = 23.0204; //choosen by fair dice roll
--- Конец кода ---
Надо разделить целую и дробную часть (в виде количества десятитысячных) и записать их в целочисленные переменные.
Быдлокодим:
--- Код: ---uint32_t integer, fractional;
integer = f;
fractional = (f - integer) * 10000;
--- Конец кода ---
Получаем в результате:
--- Код: ---integer == 23
fractional == 203
--- Конец кода ---
Что-то пошло не так...
Нужен результат:
--- Код: ---integer == 23
fractional == 204
--- Конец кода ---
Пока выкрутился так:
--- Код: ---uint32_t fract_int_text(float f, uint32_t *integer)
{
char str[sizeof("999.9999")];
uint32_t fractional;
sprintf(str, "%3.4f",f);
sscanf(str, "%u.%4u", integer, &fractional);
return fractional;
}
--- Конец кода ---
Это, конечно, работает. Но еще танцует и поет (см. https://lurkmore.to/Индусский_код).
Да и гонять эти спринтфы ссканфы на микроконтроллере накладно...
Существует ли более удачное решение для подобной задачи?
Пишем на Сях(с плюсами и без).
voidmain:
Никто мозг не вывихнул еще? :wacko:
От преобразования через текст удалось избавиться.
--- Код: ---uint32_t fract_int(float f, uint32_t *integer)
{
uint32_t t;
*i = f;
t = (uint32_t)((f - *i) * 100000) % 10;
return (f - *i)*10000 + (t >= 5 ? 1 : 0);
}
--- Конец кода ---
В общем, корень зла оказался в машинном представлении чисел с плавающей точкой в купе с правилами округления.
vavdog:
У меня такое тоже бывает — что-то схватит за душу, держит и не отпускает. И тогда или водка... или к бабам. А лучше всё вместе, сразу и много... (с)
:grin: :grin:
Змей:
:dash:
voidmain:
--- Цитата: Змей от 21.07.2017, 14:50:10 --- :dash:
--- Конец цитаты ---
Вот вот. Понапридумывают дебильных протоколов...
Кстати, видел я исходники приёмной стороны (на сервере). Там идет обратное преобразование.
Так вот там:
--- Код: ---float to_float(uint32_t i, uint32_t f)
{
char s[20];
float f;
//тут сначала вагон проверок
//........
//а потом:
sprintf(s, "%u.%u", i, f);
sscanf(s,"%f", &f);
return f;
}
--- Конец кода ---
Анекдот, бля. Обхохочешься.
Вот так на всяких ксеонах многоядерных о ста гигах оперативы хуярят говнокод и орут за новый сервак, бо этот уже не тянет.
PS: В общем, тему можно закрывать.
Задача решена. Землекопа полтора.
Навигация
Перейти к полной версии