#1 2019-12-15 03:36:50

arik
Участник
Зарегистрирован: 2019-12-15
Сообщений: 1

Ошибка оператора сравнения

Доброго всем!
Есть код, всё работает правильно и корректно, но при выводе на экран происходит "баг" отображения.
в блоке вывода на экран код:

            if      (X<5)         {tft.print("0");}
            else if (X<10)        {tft.print("  ");tft.print(X,2); tft.print(" ");}
            else if (X<100)        {tft.print(" ");tft.print(X,1); tft.print(" ");}
            else                                               {tft.print("---");}

отображаются цифры от 0 до 100, но значение 10 отрабатывает с багом в виде появление лишнего 0.
значение высчитывается с тысячными, это нужно для программы, а вот отображать их не нужно, достаточно десятых.
так вот когда значение очень близко к числу 10.000-10.009 на экране появляется лишний 0.
как только значение достигает 9.999 или 10.010 - оператор сравнения отрабатывает корректно.

как этот баг можно поправить не изменяя точность вычисления? тем более так получается, что наблюдаемый/отображаемый параметр очень часто близок к значениям 9-10-11.
Спасибо!

#2 2019-12-15 09:01:47

Watchdog
Гость

Re: Ошибка оператора сравнения

Сделайте отдельный тест и установите логику и повторяемость ошибки. Если это действительно ошибка форматирования а не интерференции кода. Слишком мало информации для выводов.

#3 2019-12-15 13:13:34

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

Никогда не пиши тексты типа

arik пишет:

Ошибка оператора сравнения

если хочешь реальной помощи. Такие тексты вызывают одно желание - поглумиться.

Запомни, если что-то идёт не так, то в 99,(9)% случаев это ошибка в твоей программе, или в твоём понимании того, как она должна работать.

Тем более, самим вопросом ты показал, что не особо то разбираешься в теме. Если бы разбирался, то обязательно указал бы какого именно типа у тебя Х.

Что касается твоего "лишнего" нуля, то он появляется тогда, когда X на самом деле меньше 10, но при округлении до 2 знаков он выглядит как 10. Вот оно и печатается как 10.00

Запусти вот этот тест и полюбуйся при каких значениях X у тебя лишний ноль появляется - прямо на границы смотри где появляется и где исчезает. И, ещё раз, никогда не пиши про ошибки компилятора, будут смеяться и глумиться. Пиши о своих ошибках.

void setup() {
  Serial.begin(57600);
  for (float X = 9.9940; X < 10.0006; X += 0.0001) {
    Serial.print(X, 4);
    Serial.print(": ");

    if (X < 5) {
      Serial.println("0");
    }
    else if (X < 10) {
      Serial.print(" ");
      Serial.print(X, 2);
      Serial.println(" ");
    }
    else if (X < 100) {
      Serial.print(" ");
      Serial.print(X, 1);
      Serial.println(" ");
    }
    else {
      Serial.println("---");
    }
  }
}
void loop() {}

#4 2019-12-15 14:04:22

arik гость
Гость

Re: Ошибка оператора сравнения

я не писал что ошибка в компиляторе, я писал что ошибка в коде оператора сравнения который я использую, и конечно, если бы я разбирался больше, вопросов бы не задавал. По тесту я вижу тоже самое что и у меня, и что это меняет? пробовал "x == 10" всё равно лишний ноль появляется. по поводу округления не совсем понял... в коде же видно, когда х меньше 10, и писал выше что когда х равен 9.99 то это так и отображается. когда же 10.010 то на дисплее красиво пишет 10.0 а вот 10.000 отображает лишний ноль.
и ещё раз - я пишу не о том что компилятор виноват, я пишу о том что не могу добится корректного вывода данных. ну так, чтоб не глумились, не писали тест ради теста, а попробовали сами увидеть что выводит в результат при Х=10.000 или 10.009

#5 2019-12-15 14:26:34

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

Я писал тест не ради теста, а ради того, чтобы ты посмотрел и подумал.  Но ты не стал этого делать, а ограничился тем, что

arik гость пишет:

не совсем понял...

Ты тест запускал? Если нет, то иди лесом, нахрена я его писал, если тебе даже лень запустить и посмотреть.

А если запускал, то не понимаю, чего тебе ещё надо, там всё видно и понятно откуда у проблемы ноги растут. Ну, смотри, вот кусок того, что этот текст выдаёт:

9.9949:  9.99
9.9950:  10.00

По первой строке: Х меньше 10? ДА. Значит, печатаем его с двумя знаками и получаем (после округления до двух знаков) 9,99
По второй строке: Х меньше 10? ДА. Значит, печатаем его с двумя знаками и получаем (после округления до двух знаков) 10,00

Чего тебе здесь непонятно? Он меньше 10, но при округлении до двух знаков, становится равным 10. Остались вопросы?

Редактировался Kaka (2019-12-15 14:27:43)

#6 2019-12-15 14:56:31

arik гость
Гость

Re: Ошибка оператора сравнения

погоди ругаться! я где то писал про округление данных? оно мне ну нужно!!! оператор сравнения мне нужен для отсечения знаков!
в моём случае, в коде, все данные идут в том виде, как они посчитаны, без округлений, они мне нужны в точном виде.
мне нужно при отображении на экране отсекать лишние знаки... может быть я вообще не правильно выбрал путь через оператор сравнения?
мне нужно чтоб при результатах данных печаталось на экран только нужное мне, пример
9.999 на экран 9.99
10.00 на екран 10.0
на сколько я понимаю, в коде который я использую это заложено
else if (X<10)          {tft.print("  ");tft.print(X,2); tft.print(" ");}
если число 9.999 печтаем два пробела потом само число с форматом 2 знаков после запятой и печатаем пробел
else if (X<100)        {tft.print(" ");tft.print(X,1); tft.print(" ");}
если число 10.00 печатем один пробел потом число с форматом 1 знак после запятой и печетаем пробел
должно быть
9.99
10.0
пробелы не важны наверное, я их для выравнивания использую. но формат знаков после запятой работает на всех цислах кроме числа равного 10.000 -10.009

#7 2019-12-15 15:21:55

г0сть
Гость

Re: Ошибка оператора сравнения

arik гость пишет:

оператор сравнения мне нужен для отсечения знаков!
...
на сколько я понимаю, в коде который я использую это заложено

Здесь используется обычное округление. Нужно отсечь лишнее - затирай.
Мой хрустальный шар показывает использование библиотеки Adafruit_GFX. Если да, то выщитай положение курсора и делай примерно так
else if (X<10)          {tft.print("  ");tft.print(X); tft.setCursor(здесь укажи нужную позицию); tft.print("    ");}

#8 2019-12-15 15:23:35

Watchdog
Гость

Re: Ошибка оператора сравнения

Тогда вам придётся описать форматирование числа самостоятельно или воспользоваться функциями из <stdio.h>.

#9 2019-12-15 15:28:35

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

arik гость пишет:

я где то писал про округление данных?

Конечно, писал!

print(X,2) означает "округлить до 2 знаков и напечатать".

arik гость пишет:

все данные идут в том виде, как они посчитаны, без округлений, они мне нужны в точном виде.

В точном виде данных типа float не бывает в природе. Они всегда округляются. На это ты и напоролся.

arik гость пишет:

мне нужно при отображении на экране отсекать лишние знаки... может быть я вообще не правильно выбрал путь через оператор сравнения?

Ну, это само собой, что по уму это делается не так, но и так может работать, если написать правильно, ты просто не понимаешь как оно устроено, потому и пишешь чё попало. Сейчас-то понял в чём проблема? Осталось только её решить? Или так и не понял?

arik гость пишет:

на сколько я понимаю, в коде который я использую это заложено
else if (X<10)          {tft.print("  ");tft.print(X,2); tft.print(" ");}
если число 9.999 печтаем два пробела потом само число с форматом 2 знаков после запятой и печатаем пробел

Похоже, ни хрена не понял. Если "если число 9.999", то "с форматом 2 знаков после запятой" оно будет 10,00. Именно это у тебя и печатается. Так и должно быть.

Если тебе надо просто отбрасывать лишние знаки, а не округлять, та отбрасывай их сам. Вместо "tft.print(X,2);" напиши "tft.print(float(int(X*100))/100,2);" это отбросит все знаки, кроме двух. Если надо отбросить все, кроме одного, то замени 100 на 10.

Редактировался Kaka (2019-12-15 15:29:46)

#10 2019-12-15 15:52:32

arik гость
Гость

Re: Ошибка оператора сравнения

да, используется Adafruit_GFX и метод затирания пробовал, не подходит, выводится много данных, код получается очень громоздким...
<stdio.h> почитаю, спасибо.
"print(X,2) означает "округлить до 2 знаков и напечатать"." ну если бы в функции принт было бы написано что округляется, даже не брался бы за такой оператор! а написано то дословно - Serial.print(val) Serial.print(val, format) - Serial.println(1.23456, 0) выводит "1" Serial.println(1.23456, 2) выводит "1.23" Serial.println(1.23456, 4) выводит "1.2346" - это не я придумал.
вот за "tft.print(float(int(X*100))/100,2);" спасибо! сейчас займусь, отпишусь.

#11 2019-12-15 16:09:59

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

arik гость пишет:

Serial.println(1.23456, 0) выводит "1" Serial.println(1.23456, 2) выводит "1.23" Serial.println(1.23456, 4) выводит "1.2346" - это не я придумал

Ну, всё правильно, выводит с округлением. Serial.println(1.65432, 0) выводит "2". Не знаю, как ты мог этого не понять.

И это, не надо оправдываться и доказывать, что ты прав. доказывай компьютеру, мне-то зачем?

#12 2019-12-15 18:15:52

arik гость
Гость

Re: Ошибка оператора сравнения

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


прав всё таки г0сть, с его замечательным хрустальным шаром smile, запечатывание лишнего 0 пока единственное решение, учитывая вышеизложенное.

всем спасибо!!! smile пойду искать функции подготовки формата данных до вывода на печать.

#13 2019-12-15 18:33:31

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

Не понял, то отбрасывание, что я тебе написал не решило проблему?
Так не бывает, ты что-то не так сделал. Показывай.

#14 2019-12-15 18:48:11

arik гость
Гость

Re: Ошибка оператора сравнения

хм... а что показывать... так как функция сравнения мне нужна, код остался не изменным, за исключением того что было предложено:
if      (X<5)         {tft.print("0");}
else if (X<10)        {tft.print(float(int(X*100))/100,2);}
else if (X<100)        {tft.print(float(int(X*100))/100,1);}
else                                               {tft.print("---");}
в таком варианте замена 100 на 10 на количество знаков после запятой не влияло, менял 2 и 1.

запечатал так, лишний 0 не появляется
if      (X<5)         {tft.print("0");}
else if (X<10)        {tft.print(X,2);tft.setCursor(80,positionY+17-10); tft.print(" ");} // запечатал ячейку пробелом где лишний 0 появлялся
else if (X<100)        {tft.print(X,1);}
else                                               {tft.print("---");}

или я не понял и от функции сравнения нужно вообще отказаться? тогда как определить чему равно число и какое количество знаков выводить?

#15 2019-12-15 18:55:55

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

Ты ещё и читать не умеешь?
Я же тебе русским языком писал, что "если надо один знак оставить, то заменяй 100 на 10". А у тебя что написано?

else if (X<100)        {tft.print(float(int(X*100))/100,1);}

Это шозанах?

Делай как сказали, только аккуратно. Это стопудово решает твою проблему. Если не получается, значит опять что-то напарил. Всё там должно быть нормально.

#16 2019-12-15 19:07:38

arik гость
Гость

Re: Ошибка оператора сравнения

а ещё возможно проблема в другом... а точнее в Adafruit_GFX.
сейчас специально запустил код с уменьшением значений ровных чисел.
100 - 10 - 1 (не функция а пример уменьшения) так вот, после 100 экран нарисовал 990, после обновления екрана (переход кнопками в другой блок отображения возврат обратно) отрисовала 99, то же самое с цифрой 10, после уменьшения отрисовал 90, после обновления экрана 9.
Пропечатал пробелами через сравнение, рисует правильно.
ещё... пример.
написал увеличение ровных чисел.
1-10-100 - если просто, то рисует так
1
10
100
если пытаюсь через сравнения выставить красиво с пробелами чтоб получилось
   1
  10
100
в результате получаю примерно такое
  1
  10
10
100
опять эта 10.00 в сравнении х<10
wink

#17 2019-12-15 19:11:43

arik гость
Гость

Re: Ошибка оператора сравнения

хм... вот ничего не меняю, только в первом сравнении пишу
else if (X<10)        {tft.print(float(int(X*100))/100,2);}
на екране два знака после запятой
ставлю так
else if (X<10)        {tft.print(float(int(X*10))/10,2);}
на экране два знака после запятой

сейчас ещё раз всё проверю...

#18 2019-12-15 19:22:16

arik гость
Гость

Re: Ошибка оператора сравнения

да, всё верно, два знака после запятой в обоих вариантах если
else if (X<10)        {tft.print(float(int(X*10))/10,2);}
пишу
else if (X<10)        {tft.print(float(int(X*10))/10,1);}
один знак после запятой

#19 2019-12-15 19:25:04

Watchdog
Гость

Re: Ошибка оператора сравнения

К графике нужен подход особый, особенно рисуя фруктовыми соками Ада. Нужно малевать а не печатать! big_smile

#20 2019-12-15 19:25:55

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 285

Re: Ошибка оператора сравнения

Простите, Вы, наверное устали. Отдохните, потом вернётесь, иначе, простите, но Вы выглядите идиотом.

arik гость пишет:

хм... вот ничего не меняю, только в первом сравнении пишу
else if (X<10)        {tft.print(float(int(X*100))/100,2);}
на екране два знака после запятой
ставлю так
else if (X<10)        {tft.print(float(int(X*10))/10,2);}
на экране два знака после запятой

А сколько Вы хотели, если Вы сами написал двойку?

У Вас как раньше было?

else if (X<10)        {tft.print(float(int(X*100))/100,2);}
else if (X<100)        {tft.print(float(int(X*100))/100,1);}

Ну так и напишите по-человечески

else if (X<10)        {tft.print(float(int(X*100))/100,2);}
else if (X<100)        {tft.print(float(int(X*10))/10,1);}

Делов-то!

Редактировался Kaka (2019-12-15 19:26:34)

#21 2019-12-15 19:34:04

arik гость
Гость

Re: Ошибка оператора сравнения

Watchdog - да да, точно что малЮвать!
Kaka - ох не внимательный... сейчас всё перепроверю.

#22 2019-12-15 19:48:12

arik гость
Гость

Re: Ошибка оператора сравнения

Kaka респектище!!! сейчас попробую на рабочем коде, но пока 10.00 не появляется... Спасибо!!!  cool

#23 2019-12-15 22:49:48

arik гость
Гость

Re: Ошибка оператора сравнения

Kaka, ещё раз спасибо! это реально рабочее решение!
поправил всё на рабочем коде, всё красиво и без глюков!

Быстрое сообщение

Введите сообщение и нажмите Отправить

Подвал раздела