# Print with round towards zero instead of round to nearest

When printing with one decimal place, Arduino's `Serial.println()` rounds numbers like `123.89` to “123.9”. Is there any way to change the rounding mode? For some reasons I want the value to be rounded towards zero (i.e., truncated) to one decimal place, like `123.89` → “123.8”.

here is the code

``````void setup() {
Serial.begin(9600);

}

void loop()
{
A = (A/1023)*5.0;
Serial.print("A = ");
Serial.println(A,3);
float B = A*10;
Serial.print("A * 10 = ");
Serial.println(B,1);
delay(1000);
}
``````

the output is

``````A = 2.473
A * 10 = 24.7
A = 2.488
A * 10 = 24.9
A = 2.517
A * 10 = 25.2
A = 2.527
A * 10 = 25.3
A = 2.507
A * 10 = 25.1
``````

instead I want the output to be like this

``````A = 2.473
A * 10 = 24.7
A = 2.488
A * 10 = 24.8
A = 2.517
A * 10 = 25.1
A = 2.527
A * 10 = 25.2
A = 2.507
A * 10 = 25.0
``````

is it possible ?

• We can't tell you what you're doing wrong if we don't know what you're doing. – Ignacio Vazquez-Abrams Jun 14 '18 at 16:20
• This is not the serial monitor. It is the serial output statements in your sketch, or more likely the floating point format itself. You might perhaps consider using a `double` instead of a `float`. But it's also unclear that the value being printed is not already the most accurate decimal approximation of the value internally stored. Without your code this is unanswerable. – Chris Stratton Jun 14 '18 at 16:24
• So you want the output to be truncated instead of rounded? 2.59 as 2.5 instead of 2.6? – Craig Jun 14 '18 at 17:15
• What you are describing is by no means a value that is "exact up to one decimal place" Your major problem here is that you've failed to really articulate that you want a value that is intentionally inexact. Do you have any actual justification for distorting your data like this??? – Chris Stratton Jun 14 '18 at 17:54
• Note that most decimal numbers are not exactly representable as floats. For example, if you type `float x = 23.40;`, the compiler rounds that number to the nearest representable float, which happens to have the exact value 23.3999996185302734375. If you truncate this to one decimal place, then `23.40` ends up being printed as “23.3”! – Edgar Bonet Jun 14 '18 at 20:53

A cheap trick to round a number to one decimal place (in "chop-off mode") is to multiply it by 10, convert it to an integer, and divide by `10.0f` again:

``````float myVal = 123.89f;
myVal = (long)(myVal * 10) / 10.0f;
// = ((long)1238.9) / 10.0f
// = 1238 / 10.0f
// = 123.8
``````

You can then print this modified number to the serial monitor.

This method can also be generalized to other precisions. For 2 decimal places, we just have to multiply by 10^2 (100) and divide by 10^2. A macro would be:

``````#define TRUNCATE(val, numDecimalPlaces) \
(float)(((long)((double)(val) * pow(10, (numDecimalPlaces) * 1.0f))) / (pow(10, (numDecimalPlaces)* 1.0f)))
``````

Note: You don't have to actually dynamically compute `pow(10, numDecimalPlaces)`, you can also create macros for each decimal precision from 1 to `x` and simply precompute that value (100, 1000, 10000, ..).

The same can also be achieved by using the standard library function `trunc` from `math.h`:

``````#define TRUNCATE_TO_ONE(val) \
(trunc((val) * 10.0f) / 10.0f)
``````

Here's a small sketch in which it is demonstrated:

``````#include <Arduino.h>

#define TRUNCATE(val, numDecimalPlaces) \
(float)(((long)((double)(val) * pow(10, (numDecimalPlaces) * 1.0f))) / (pow(10, (numDecimalPlaces)* 1.0f)))

#define TRUNCATE_TO_ONE(val) \
(trunc((val) * 10.0f) / 10.0f)

void printValueFormatted(float value, int numDecimalPlaces) {
//format correctly
char buf;
char* res = dtostrf(value, sizeof(buf)-1, numDecimalPlaces, buf);

//skip over empty chars
while(*res == ' ')
res++;

//print buffer
Serial.println(res);
}

void setup(void)
{
Serial.begin(115200);
}

void loop(void)
{
float myVal = 123.8978f;
printValueFormatted(myVal, 4);
printValueFormatted(TRUNCATE(myVal, 1), 1);
printValueFormatted(TRUNCATE(myVal, 2), 2);
printValueFormatted(TRUNCATE(myVal, 3), 3);
printValueFormatted(TRUNCATE(myVal, 1), 4);
printValueFormatted(TRUNCATE(myVal, 2), 4);
printValueFormatted(TRUNCATE(myVal, 3), 4);
delay(1000);
}
``````

Prints

``````123.8978
123.8
123.89
123.897
123.8000
123.8900
123.8970
``````
• I am having some problems when I am using this piece of code.. I am using serial print to print some analog values from the A0 and A1 pin of an arduino uno and dividing the values from each other to get a ratio. Eg: `A = A0` and `B = A1` after that `C = A/B` and printing values `C * 100` on the serial monitor. Everything is working perfectly fine until I made the value of B very low. Applying this code giving me negative values of the ratio and without it it is giving perfect values which is rounded to the nearest. Is there anything else to overcome this problem? – Peouse Dutta Jun 15 '18 at 10:31
• @PeouseDutta `int` is a 2-byte integer with a range of about -32K to +32K. Might be too small for you if you suddenly multiply by 100. I updated the code to convert it to `long` instead. – Maximilian Gerhardt Jun 15 '18 at 11:30
• Note that `pow()` is expensive if you don't have an FPU. – Edgar Bonet Jun 15 '18 at 12:03
• I addressed this above. The pow is only needed to compute 10^x, just precompute it. – Maximilian Gerhardt Jun 15 '18 at 12:13
• I did a small test and it turns out that a call to `pow()` with compile-time constant arguments gets optimized out by gcc into a constant. So you should be fine with `pow()`. Check the generated assembly if in doubt. – Edgar Bonet Jun 15 '18 at 12:27

Use the given [function] for your problem. This function works on a pre-defined [algorithm].

``````int roundTowardZero(float number, int decimal_place) {
float round_number = round(number);
if(round_number > number) round_number = round_number - 1;
float deci = (number - round_number) * pow(10, decimal_place);
float round_decimal = round(deci);
if(round_decimal > deci) round_decimal = round_decimal - 1;
round_decimal = round_decimal / pow(10, decimal_place);
total_number = round_number + round_decimal;
}
``````

Place this function above `int setup()`

like:

``````int roundTowardZero( ... ) {
...
}
void setup() {
...
}
void loop() {
...
}
``````

Function syntex is like this : `roundTowardZero([Enter a Decimal Value], [Enter Round Place Value])` Example :`roundTowardZero(123.89, 1) //Output : 123.8`

Please comment below is you find any problem or face any error.