Округление до первой значащей цифры
Я хочу округлить десятичное число (x), но мне нужно сделать это по-разному, в зависимости от того, как оно есть. Если он содержит целочисленные значащие цифры, мы округляем до ближайшего целого числа, а если нет, то округляем до первой значащей цифры. Таким образом, с этими примерами чисел произойдет следующее: 11.871->12, 11.177->11, 37.233->37, 37.779->38, 0.578->0.6, 0.544->0.5, 0.0257->0.03, 0.0223->0.02... (Числа могут содержать больше или меньше знаков после запятой, чем в приведенных примерах).
Чтобы реализовать это, я создал функцию (type), в которой мы проверяем, имеет ли самая значащая цифра тип integer или decimal. Эта функция возвращает эту характеристику числа в виде "строки". Поэтому, если самая значащая цифра является целым числом, мы просто используем функцию "round ()". Однако я не знаю, как округлить число до первой значащей цифры (функция roundto_fsd()). Кто-нибудь знает о какой-либо функции, способной сделать это, или о каком-либо методе для этого?
float x;
char type(float number) {
char type[8];
if (int(number) != 0) {
type = "integer";
} else {
type = "decimal";
}
return type;
}
float roundto_fsd(float number) {}
void setup() {
Serial.begin(9600);
if (!type(x).compareTo("integer")) {
Serial.println(round(x));
} else if (!type(x).compareTo("decimal")) {
Serial.println(roundto_fsd(x));
}
}
void loop() {}
@Libegria, 👍1
1 ответ
Прежде всего, позвольте мне уточнить, что в float нет ничего “десятичного”
:
float
- это двоичное (не десятичное) число с плавающей запятой.
Функция Serial.println()
выполняет двоичное преобразование в десятичное
с целью представления числа в виде удобочитаемого текста. Если вам
нужно определенное количество десятичных цифр после исходной точки, вы
должны попросить Serial.println()
предоставить их. Это делается путем передачи
этого числа в качестве второго параметра:
Serial.println(sqrt(2)); // печатает "1.41" (по умолчанию 2 десятичных знака)
Serial.println(sqrt(2), 0); // печатает "1"
Serial.println(sqrt(2), 5); // печатает "1.41421"
Теперь возникает вопрос: как вычислить количество требуемых цифр после
точки основания? Это зависит от того, насколько велик float
. Если оно
меньше 1, но больше или равно 0,1, вам нужна только одна цифра. Если
оно в десять раз меньше этого, вы хотите ввести цифры и так далее:
числа цифры
───────────────────
[1, +∞) 0
[0.1, 1) 1
[0.01, 0.1) 2
[0.001, 0.01) 3
Я предлагаю многократно умножать ваш float
на 10, пока он не станет ≥ 1,
и подсчитайте, сколько раз вам пришлось это делать:
/* Сколько знаков после запятой нужно напечатать. */
int decimal_places(float x)
{
int i = 0;
while (x < 1) {
x *= 10;
i++;
}
return i;
}
Вы могли бы использовать эту функцию следующим образом:
Serial.println(x, decimal_places(x));
Обратите внимание, что при таком подходе существует небольшая проблема. Если вы попытаетесь напечатать
0.97, decimal_places()
скажет, что вам нужен один десятичный знак, а
Serial.println()
выведет “1.0”. Если вы предпочитаете, чтобы он печатал
“1”, затем измените условие цикла в decimal_places()
на:
while (x < 0.95)
Предостережение: все это предполагает, что все числа, которые вы хотите напечатать
, строго больше нуля. В противном случае decimal_places()
будет иметь
бесконечный цикл.
- Как написать функцию, возвращающую матрицу?
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
Спасибо! Использует "while(x<0.95)" условие, потому что Serial.print() выполняет раунды?, @Libegria
@Libegria: Это потому, что
Serial.print()
округляется до ближайшего, то есть 0,97 будет округлено до 1,0, но 0,93 будет округлено до 0,9., @Edgar Bonet