Rounding float number

Hi, I’m a new person with Processing and Java language also.
So I’m sorry if my question is stupid and it bothers you.
I’m trying to calculate float numbers then print out the result. My code as below:

float x, y ;
float x1, y1, z;

void setup() {
  x = 1.54367;
  y = 14.4876;
  x1 = float(nf(x, 0, 2));
  y1 = float(nf(y, 0, 2));
  z = x1 + y1;
}
void draw() {
  print("x = ", x1, "; ");
  println("y = ", y1);
  println("z = ", z);
}

Could you please tell me why the result of z is 16.029999 instead of 16.03 ?

1 Like

Hi,
the problem lies in the way computers store float numbers. You can look that up on Wikipedia if you want to get more specific.

Wikipedia Floating Point Numbers

Simply put: There is no way to store exactly 16.03.
The problem gets worse when you do multiple calculations in a row.

To solve your problem, you could multiply by 100, round and then display accordingly.

Happy new year.

2 Likes

That’s because floating point numbers can’t really have enough precision to store exactly 16.03, as noted above.

You could try using double instead of float for even higher precision as double uses 64 bits opposed to float using 32 bits, or use println("z = ", nf(z,0,2)); instead to round the number.

2 Likes

Thank you very much MxFxM.

I’m trying to control a servo motor, so how can I send a correct number of turning to servo motor such as: 1,2 round or 2.5 round?
As your explanation, I have to calculate all float variables as original value --> round up only the last result then send this result to servo moto. Am I correct?

Happy New Year!

Yes. For best precision of the calculations, it makes sense to never round - except if it’s needed or when you need to display/send a number in an understandable format.

Also, wouldn’t your servo motor be okay with 16.029999? :smiley:

My first guess would be that 16.029999 could also work. And given that it is really close to 16.03 i doubt one might see / measure the difference :smiley:

:joy: of course NO. That’s reason why my head is burning. When I tried to control servo motor through Arduino board, it always turned wrong number of turn.
I guess that the problem in Arduino is as same as in Processing.
Thank you very much for your help!

i would say that the float / print with 2 dec / float / add …
never should be used.

so just for the above code:

float x, y, z;

void setup() {
x = 1.54367;
y = 14.4876;
z = x + y;
println("raw: x = "+ x +"; y = "+y+"; z = "+z);
println("nf2: x = "+nf(x,1,2)+"; y = "+nf(y,1,2)+"; z = "+nf(z,1,2));
/*
raw: x = 1.54367; y = 14.4876; z = 16.031271
nf2: x = 1.54; y = 14.49; z = 16.03
*/
}


now regarding arduino:
as far i remember a servo needs something like 0 … 127 ?
so actually rounding up and down and print and calc float again and map to int
get the calculation, data transport and data usage alligned

  • calc in float
  • map to int
  • send int

so here again the first question is: what is 16.03 ??
is it like 16 % of 100.00 or of 360 deg
now can use
https://processing.org/reference/map_.html

2 Likes

Thank you very much kll!
I’ll try to follow your instruction.:sweat_smile:
Do you know any reference document about : control servo motor by Arduino board?
I would like to read more.

What servo motor and control boards are you using exactly? Any shields etc.?

@MxFxM I use Arduino Uno board - Module TB6560 - Servo motor SUMTOR 1.8 degree, 3.0A.

I didn’t have a deeper look into stepper motors myself but when you google search for your TB6560 driver module and arduino you find a lot of projects where people used those parts including wiring and example codes.

You might also want to look at the datasheet for your driver module to understand the different settings and how they can be set depending on input signals.

[Datasheet for TB6560](file:///C:/Users/muelmaxf/Downloads/TB6560AHQ_datasheet_en_20141001.pdf)

2 Likes

and for the code:

https://www.arduino.cc/en/reference/servo

1 Like

I figured that’s not the kind of servo he uses but the arduino reference site in general will help a lot

1 Like

@kll, @MxFxM Thank you so much for your help! I’ll study more. :smiling_face_with_three_hearts::smiling_face_with_three_hearts:

1 Like

and next time give us some words about your project,
what you want use the processing for and what the big stepper/servo is about…
because next week a other community member might need YOUR help,
and after you got it running : YOU are the expert!



float x, y ;
float x1, y1, z;

void setup() {
  x = 1.54367;
  y = 14.4876;
  x1 = float(nf(x, 0, 2));
  y1 = float(nf(y, 0, 2));
  z = x1 + y1;
  
  z = round_decimals(z, 2); 
  
  noLoop();
}
void draw() {
  print("x = ", x1, "; ");
  println("y = ", y1);
  println("z = ", z);
}

float round_decimals(float f, int d) {
  int pow = (int) pow(10, d); 
  f *= pow;
  f = (int) round(f);
  f /= pow;
  return f;
}
1 Like

@kll. Thank you very much for your encourage.
I would like to share my codes for other members who may concern about this matter.
When you change '“x” value in processing, motor will turn the corresponding round as its value.
I use Arduino Uno board + driver module TB6560 + Step motor SUMTOR - 57HS7630A (1.8deg,3A)

Processing code:

import processing.serial.*; 
import controlP5.*;
import java.util.*;

Serial port;                       // Create object from Serial class
ControlP5 cp5;
String a, status, direc, old_direc, new_direc;
boolean order;
int x,count ;
float cycle,b =0;

void setup() { 
  size(200, 200); 
  noStroke(); 
  smooth();
  background(0);
  //frameRate(10); 
  // Open the port that the board is connected to and use the same speed (9600 bps)
  port = new Serial(this, Serial.list()[0], 9600); 
  port.bufferUntil(10);
  cp5 = new ControlP5(this);
  List l = Arrays.asList("trai", "phai");

  cp5.addScrollableList("abc")
    .setPosition(10, 10)
    .setSize(50, 100)
    .setBarHeight(20)
    .setItems(l)
    ;
} 

void draw() { 
  background(255); 
  status = cp5.get(ScrollableList.class, "abc").getLabel();
  cycle = 1.0/9.0;
  //x = int(cycle);
  
//loop 50 times to get stable value of cycle
  if (count < 50) {
   count = count + 1;
   b = b + cycle;
  }
   x = int(b/50*100);
  
 
  if (status == "phai") {
    fill(204);                     //change color
    direc = "R " + x;              // and direction is set to Right
    //new_direc = direc;
  } else if (status == "trai") {
    direc = "L " + x;
  } else {
    direc = "N 0";                    // direction is nothing
  }

  if (mouseOverRect() == true) {  // If mouse is over square,
    order = true;                    // turning order = true if (status == "trai" || status == "phai") {
    fill(204);                     // change color and  
    //direc = "Ln" + x;              // direction is set to Left
    old_direc = new_direc;
    new_direc = direc;
  } else {                           // If mouse is not over square,
    fill(0);                         // change color and
    order = false;                   // turning order = false
    old_direc = new_direc;
  } 


  //send information to Arduino if turning order = true
  
  if ( order == true & old_direc != new_direc) {
    if (count == 50){
    port.write(direc);
    old_direc = new_direc;
    count = 0;
    b = 0;
    println(old_direc, " vs ", new_direc);
    }
  } else {
    port.write("N 0");
    println("Non");
  }
  
  
  rect(50, 50, 100, 100);          // Draw a square
  //println(a);
} 

//void serialEvent(Serial p) {
//  a = p.readStringUntil('\n');
//}

boolean mouseOverRect() {        // Test if mouse is over square 
  return ((mouseX >= 50) && (mouseX <= 150) && (mouseY >= 50) && (mouseY <= 150));
} 

Arduino code:

int _step = 0, Distance = 0, count; // Record the number of steps we've taken void setup()
int new_loop, old_loop;
String new_dir, old_dir;                          // Data received from the serial port
void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available())
  { // If data is available to read,
    new_dir = Serial.readStringUntil(' ');           // read it and store it in val
    new_loop = Serial.parseInt();
  }
  if ((new_dir != old_dir) )
  {
    old_loop = new_loop;
    old_dir = new_dir;
    _step = old_loop * 3200 / 100;
    //  Distance = 0;

    if (old_dir == "L")
    {
      digitalWrite (8, LOW);
    }
    else if (old_dir == "R")
    {
      digitalWrite(8, HIGH);
    }
  } else {
    _step = 0;
    Distance = 0;
  }
  count = 0;
  for (int x = 0; x < _step; x++)
  {
    digitalWrite(9, HIGH);

    delayMicroseconds(200);

    digitalWrite(9, LOW);

    delayMicroseconds(200);


    Distance++; // record this step // Check to see if we are at the end of our move
    if (Distance == _step){
      Distance = 0;
      break;
    }

  }

  if (new_loop != old_loop) {
    digitalWrite(4, HIGH);
  } else {
    digitalWrite(4, LOW);
  }
}

Hope that it will help somebody who may concern!

2 Likes

Thank you so much for sharing you solution, @lodolfo