I want to round a decimal number (x),but I need to do it differently depending on how it is. If it has integer significant digits, we round to the nearest integer, and if not, we round to the first significant digits, So the following would happen with these example numbers: 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... (The numbers could have more or less decimal places than in the examples).
To implement this, I have created a function (type) in which we check if the most significant digit is of type integer or decimal. This function returns this characteristic of the number in the form of a "string". So if the most significant digit is an integer we just use the "round()" function. However, I don't know how to round a number to the first significant digit (roundto_fsd() function). Does anyone know of any function capable of doing this or any method to do it?
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() {}
#include <stdio.h>
#include <math.h>
int main() {
float i=5.4;
while(1) {
scanf("%f",&i);
if(i>=1.0)
printf("round of %f is %f\n", i, round(i));
else
printf("round of %f is %f\n", i, round(i*10.0f)/10.0f);
}
return 0;
}
a run gives
11.87
round of 11.870000 is 12.000000
11.17
round of 11.170000 is 11.000000
37.2
round of 37.200001 is 37.000000
37.8
round of 37.799999 is 38.000000
.578
round of 0.578000 is 0.600000
.544
round of 0.544000 is 0.500000
I have presented in post #6 what OP has requested above. He has neither asked for a unified approach nor for saving the results in variables. (Do you think that there possibly exits a unified approach?)
#include <stdio.h>
#include <math.h>
int main() {
float i=5.4;
while(1) {
scanf("%f",&i);
int divisor=1;
while(divisor*i < 1.0f) divisor*=10;
printf("divisor %d round of %f is %f\n", divisor, i, round(i*divisor)/divisor);
}
return 0;
}
a run gives
11.871
divisor 1 round of 11.871000 is 12.000000
11.177
divisor 1 round of 11.177000 is 11.000000
37.33
divisor 1 round of 37.330002 is 37.000000
37.78
divisor 1 round of 37.779999 is 38.000000
5.32
divisor 1 round of 5.320000 is 5.000000
5.78
divisor 1 round of 5.780000 is 6.000000
.532
divisor 10 round of 0.532000 is 0.500000
.578
divisor 10 round of 0.578000 is 0.600000
.0532
divisor 100 round of 0.053200 is 0.050000
.0578
divisor 100 round of 0.057800 is 0.060000
.00532
divisor 1000 round of 0.005320 is 0.005000
.00578
divisor 1000 round of 0.005780 is 0.006000
.000532
divisor 10000 round of 0.000532 is 0.000500
.000578
divisor 10000 round of 0.000578 is 0.000600
serial.print() in my shared code is set to print to 4dp!!!!
atof() output is still 0.03!
that is a difference between rounding off and number of decimal places btw
OP also said:
so pending his input, example below could be better suited for his purpose as alternative to reply#18 code.
(version2 section in the code might be more elegant but version1 IMHO is probably more 'efficient' )
#define Str_Len 10 //size array such that smallest intended decimal value can fit in
void setup()
{
float myNum[8] = {11.871, 11.177, 37.233, 37.779, 0.578, 0.544, 0.0257, 0.000223};
Serial.begin(115200);
for (int i = 0; i < 8; ++i) {
if (myNum[i] >= 1) {
long y = myNum[i] + 0.5;
Serial.println(y); //print out integer
}
else {
char s[Str_Len];
//create a string of float number in scientific format rounded to first significant digit
dtostre(myNum[i], s, 0, 0);
Serial.print(s);
Serial.print(", ");
//convert scientific format string to correcponding decimal format (works for up to 9dp)
//-----------------------------------------------------------------*/
//version 1
char d = s[0], j = (s[4] & 0x0F) + 1;
memset(s, '0', Str_Len);
s[1] = '.';
s[j++] = d;
s[j] = '\0';
//-----------------------------------------------------------------*/
//version 2
//dtostrf(atof(s), 3, s[4] & 0x0F, s);
//-----------------------------------------------------------------*/
Serial.println(s);
}
}
}
void loop()
{
}