и как Вы это проверили?Проверил, не работает так как надо, просто добавляет ,0 к uint32.
и как Вы это проверили?Проверил, не работает так как надо, просто добавляет ,0 к uint32.
Ну как, если до этого число 12.3 это в int 0x4144cccd или 1095027917 или x1=52429 x2=16708, и преобразование работает правильно, то просто присвоить тип float дает на выходе 1095027968.0и как Вы это проверили?
Ну все верноНу как, если до этого число 12.3 это в int 0x4144cccd или1095027917 или x1=52429 x2=16708, и преобразование работает правильно, то просто присвоить тип float дает на выходе 1095027968.0
А как внутреннее представление посмотреть? Мне нужно на вход функции подать 2 int на выходе получить float которое я могу записывать в файл или вывести в лог, именно в формате 12.3 так как это сделано тут IEEE-754 Floating Point Converter, только в обратную сторону, для тех int которые дают на выходе float >1 все OK, а если число меньше 1 зависает, скорее всего из-за нехватки времени на возведение в степень.Ну все верно
Вы преобразовали число 1095027917 из формата int в формат float.
Число не изменилось, а изменилось его внутреннее представление. т е если посмотрите двоичное представление байт числа то обнаружите и мантиссу и порядок в доп коде с удаленным знаком. Т е внутреннее представление у Int и float этого числа разное.
Вы что хотите ?
------------------------------
double pow(double x,double y)
{
double z , p=1;
if(y<0)
z = fabs(y);
else
z = y;
for(int i=0; i<z ; ++i)
{
p *= x;
}
if(y<0)
return 1/p;
else
return p;
}
float ICACHE_FLASH_ATTR int_float(uint32 x1, uint32 x0)
{
uint32 value = (x1<<16) | x0;
uint32 b=value & 0x7fffff;
double e=((value>>23) & 0xff)-127;
double m=1+b*pow(2, -23);
float p=pow(2.0, e);
float result=m*p;
if (value & 0x80000000) {
result=-result;
}
return result;
}
Для начала, os_prinf в esp не поддерживает fp форматы, функцию вывода придется писать самому. Это раз. Два, возводить 2 в степень надо сдвигом влево, ну или вправо, если это отрицательная степень. Ну и три, зачем нужен этот "закат солнца вручную"? Связываться с fp для отсутствующего в библиотеке его вывода? Бессмысленно. Или считайте все в fp, или считайте в целых, а выводите отдельно целую, отдельно дробную части os_printf("%d.%d", mantissa, exponenet); Если считаете в fp, то вывод его не то чтобы сложен, но пописать придется. Я написал вывод вида "1.234k" для числа 1234.0, но там если посмотреть понятно как выводить и в других форматах. Ну оно в строку выводит, потом ее напечатать куда-то надо. Ну и преобразовать целое в fp надо не побитно руками, а просто double d = i+j/100.0; если i - целая часть, а j - сотые.А как внутреннее представление посмотреть? Мне нужно на вход функции подать 2 int на выходе получить float которое я могу записывать в файл или вывести в лог, именно в формате 12.3 так как это сделано тут IEEE-754 Floating Point Converter, только в обратную сторону, для тех int которые дают на выходе float >1 все OK, а если число меньше 1 зависает, скорее всего из-за нехватки времени на возведение в степень.
Можете рассказать что Вы делаете?А как внутреннее представление посмотреть? Мне нужно на вход функции подать 2 int на выходе получить float которое я могу записывать в файл или вывести в лог, именно в формате 12.3 так как это сделано тут IEEE-754 Floating Point Converter, только в обратную сторону, для тех int которые дают на выходе float >1 все OK, а если число меньше 1 зависает, скорее всего из-за нехватки времени на возведение в степень.
Все что надо и так выводится и печатается, я же написал для чисел >1 все норм.Для начала, os_prinf в esp не поддерживает fp форматы, функцию вывода придется писать самому. Это раз. Два, возводить 2 в степень надо сдвигом влево, ну или вправо, если это отрицательная степень. Ну и три, зачем нужен этот "закат солнца вручную"? Связываться с fp для отсутствующего в библиотеке его вывода? Бессмысленно.
Да, это если есть целые и сотые, вот я и пытаюсь получить целые и сотые, 2 int это пара регистров Modbus в формате float, на их появление я не могу влиять.Или считайте все в fp, или считайте в целых, а выводите отдельно целую, отдельно дробную части os_printf("%d.%d", mantissa, exponenet); Если считаете в fp, то вывод его не то чтобы сложен, но пописать придется. Я написал вывод вида "1.234k" для числа 1234.0, но там если посмотреть понятно как выводить и в других форматах. Ну оно в строку выводит, потом ее напечатать куда-то надо. Ну и преобразовать целое в fp надо не побитно руками, а просто double d = i+j/100.0; если i - целая часть, а j - сотые.
Наоборот, есть два регистра Modbus в формате int являющиеся передаваемой переменной в формате float, и из них надо собрать float.Можете рассказать что Вы делаете?
---------------------------
Пока из Вашего смутного рассказа я понял, что у вас есть число записанное в формате float, но в программе вы его получили в виде uint32.
union {Наоборот, есть два регистра Modbus в формате int являющиеся передаваемой переменной в формате float, и из них надо собрать float.
Да, это оно спасибо, уже и с отрицательными заработало, единственно заметил не всегда корректно "-" отображает и иногда разряды теряются, подскажите как правильно перевести в строку, до этого я делал так:union {
uint32 i[2];
double a;
}x;
x.i[0]=reg1; x.i[1]=reg2;
x.a -это double (8байт)
========================
если надо float (4 байта то)
union {
uint16 i[2];
float a;
}x;
char* fts(char* buffer, float value)
{
os_sprintf_fd(buffer, "%d.%d,", (int)(value),(int)(fabs((value - (int)value)*1000)));
return buffer;
}
-------------------------------Да, это оно спасибо, уже и с отрицательными заработало, единственно заметил не всегда корректно "-" отображает и иногда разряды теряются, подскажите как правильно перевести в строку, до этого я делал так:
Код:char* fts(char* buffer, float value) { os_sprintf_fd(buffer, "%d.%d,", (int)(value),(int)(fabs((value - (int)value)*1000))); return buffer; }
Если в modbus это 32хбитные float, то это тип float у ESP, скорее всего стандартный IEEE-754, просто делаетеВсе что надо и так выводится и печатается, я же написал для чисел >1 все норм.
Да, это если есть целые и сотые, вот я и пытаюсь получить целые и сотые, 2 int это пара регистров Modbus в формате float, на их появление я не могу влиять.
Я пару сообщений назад прицепил код для перевода fp в строки. Там есть с округлением тонкости, надо на один десятичный разряд вперед смотреть, чтобы правильно округлять.Да, это оно спасибо, уже и с отрицательными заработало, единственно заметил не всегда корректно "-" отображает и иногда разряды теряются, подскажите как правильно перевести в строку, до этого я делал так:
Добрый день, использую Ваш функцию для печати float все норм, но на определенных значениях есть провалы/выбросы значений, я так понимаю это и есть "тонкость" как это обойти, я использую задание кол-ва знаков после запятой в диапазоне от 0 до 3, вчера попробовал стороннее решение, на нем все норм, но иногда появляются буквы/знаки после запятой.Я пару сообщений назад прицепил код для перевода fp в строки. Там есть с округлением тонкости, надо на один десятичный разряд вперед смотреть, чтобы правильно округлять.
Там, вроде, все просто и прозрачно, можно примеры чисел, на которых возникают проблемы?Добрый день, использую Ваш функцию для печати float все норм, но на определенных значениях есть провалы/выбросы значений, я так понимаю это и есть "тонкость" как это обойти, я использую задание кол-ва знаков после запятой в диапазоне от 0 до 3, вчера попробовал стороннее решение, на нем все норм, но иногда появляются буквы/знаки после запятой.
Насколько я понял, это может происходить на разных числах, как пример первый график, на нем четко видно округление до целых чисел, прямо "забор" прослеживается, на синусоиде все более предсказуемо, я выделил красным одну из частей где это происходит. Возможно это связано с точностью самого float. Для проверки нашел другой пример по выводу float, на нем эта же синусоида без искажений, но там количество знаков после запятой не регулируется.Там, вроде, все просто и прозрачно, можно примеры чисел, на которых возникают проблемы?
Набросал тестикНасколько я понял, это может происходить на разных числах, как пример первый график, на нем четко видно округление до целых чисел, прямо "забор" прослеживается, на синусоиде все более предсказуемо, я выделил красным одну из частей где это происходит. Возможно это связано с точностью самого float. Для проверки нашел другой пример по выводу float, на нем эта же синусоида без искажений, но там количество знаков после запятой не регулируется.
#include <stdio.h>
#include <math.h>
#include "strnum.h"
void main(void)
{
char str1[256];
char str2[256];
FILE *fo = fopen("sin.txt", "wt");
if (fo)
{
for(int i = 0; i<360; i++)
{
float f = sin(i*M_PI/180.0);
d2scistrup(str1, f, "", 3, 0);
sprintf(str2, "%1.3f", f);
fprintf(fo, "%i;%s;%s;\n", i, str1, str2);
}
fclose(fo);
}
}