Global or local variable problem

Hi all, I have got a problem with this coding. It is probably to do with global or local variable. This coding gives b=0. when it clearly should not be 0.
int d;
float b;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("input value for variable d: ");
while (Serial.available() == 0) {
}
d = Serial.parseInt();
Serial.print("d=");
Serial.println(d);
b=(360/365*(d-81));
Serial.print("b=");
Serial.println(b);
}
How can I fix this?

360/365 is the culprit. Integer division gives you an integer result. In this case, 0.

Use 360.0/365.0 to get float division and a float result.

Oh, and use the <CODE/> tool next time to format your code, please? The harder you make it to read your code, the fewer people there are who will.

b=((float)360/365*(d-81));

I have done my best to make my worst global/local example sketch...

int a = 9600; // global "a"
void setup() {
  Serial.begin(a); // using the global variable value of "a"
  Serial.println(a); // global "a"

  int a = 2; // this new "a" is locally defined here, in "setup()"

  for (int a = 7; a < 9; a++) { // this new "a" is local only inside "for"
    Serial.println(a); // this "a" is local to "for"
  }

  Serial.println(a); // local "a" from the definition inside "setup"
}

void loop() {
  Serial.println(a); // this is the global "a"
  while(1);
}
1 Like

Please use code tags when posting code. Edit your post, select all code and click the <CODE/> button; next save your post.

1. Use "< CODE >" tag so that your sketch appears as follows:

int d;
float b;

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

void loop() 
{
   Serial.print("input value for variable d: ");
   while (Serial.available() == 0) 
   {
         ;  //wait until a character comes from Serial Monitor
   }
   d = Serial.parseInt();
   Serial.print("d = ");
   Serial.println(d);
   //b = (360/365*(d-81));
   b = (360.0/365*(d-81));
   Serial.print("b = ");
   //Serial.println(b);
   Serial.println(b, 3);   //3-digit after decimal point
}

2. Your both variables (d and b) are global. They can be accessed from any function of your sketch.

3. Here, the concerns are:
data types of the variables and operands (360 and 365).
order of operator evaluation in C++ when / and * operators appear at the same time in an expression --- it is always from left-to-right.

b = (360/365*(d-81));

So, 360/365 will be evaluated first and the result (0.986) would be rounded to 0 as both operands (360 and 365) are integers. As a result, b turns out to be: 0*(d-81) = 0.

You can preserve 0.986 by declaring 360/365 as 360.0/365.0 (now 360.0/365.0 is a floating point number). As a result, b will appear as: 0.986*(d-81).

4. Upload sketch of Step-4 and enter 82 from the InputBox of the Serial Monitor with "No line ending" option . Check that the Serial Monitor shows: 0.986. Observe the changes that I have made in the following two lines of your sketch.

 //b = (360/365*(d-81));
   b = (360.0/365*(d-81));
   Serial.print("b = ");
   //Serial.println(b);
   Serial.println(b, 3);   //3-digit after decimal point

Sorry about code tool. Didn't know how to use it. In your division you use only 1 decimal place. Are you only going to get a 1 decimal place result. float gives you multiple decimal places. Should you use say 360.00000/365.00000 to get 5 decimal places? or will you get a float result by just using 365.0. or should you use maximos solution? Never came across anything like this before even though I have done a lot of coding. Always thought I would get multiple decimal points when using real numbers and not variables. That is how you expect it to be.

You're making it way more complicated than it is. It's very simple.

Integer division gets you an integer result.

Float division gets you a float result.

A number with a decimal point is a float.

A number without a decimal point is an integer.

That's all there is to it.

3 Likes

So you might want to look at this How to get the best out of this forum before you proceed any further.

Also as your code doesn't seem to actually read the serial port, then

Is never going to change from its initial value of zero anyway. All global variables without a value in the declaration default to a value of zero.

In what language have you done your coding? Different programming languages have different rules.
In Javascript, 1 / 2 will give you 0.5 as the answer.
In C++, 1 / 2 will give you 0 as the answer. If you want 0.5 as the answer, you could, for example, use 1.0 / 2.0 , and remember to store the result in a float or a double (not in an int, or you will lose everything after the decimal point).

1 Like

unfortunately it turns out not to be so simple. maximos use of float is' b= ((float)360/365*(d-81) ' .Using d =82 b=.99. 360/365 is actually .986301369. Floating point numbers are supposed to give 6 to 7 places altogether including decimals. Here you are only getting 2. I need more precision.
It seems very odd to put 'float' in brackets. It did compile ok. Can I get some better coding from you guys to get better precision as it should be for 'float'.

"better coding from us"?

I think I'm done here. Good-bye.

1 Like

Use Serial.print(b,7);
By default only 2 decimals are printed.
If you do not like (float)360, use float(360).

What is maximos?
I have never seen two decimal points define a number what does that mean in what language.

No you are not!.

On an Arduino float and double is the same precision. Note that a float is only an approximation to a number.

Remember that you are the one asking the question, it is you that doesn't know stuff about this questions. So insulting the very knowledgeable people here is not going to win you any friends.

Please reflect on this point.

If you are not satisfied by the answers you get from people who love this platform and volunteer who give free advice, then we will gladly refund twice what you payed for it. Using integer maths only.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.