float -> integer divison

Hi guys.

The problem is that I cant find the eqvivalent math function for " ** " (don't know witch language this is, basic?)

If I'm right the ** is a divider that divides float and deliver a rounded integer

example:

9/2 = 4.5
9\2 = 5

My function:

 float FNday (float y,float m,float d,float h) {

return 367 * y - 7 * (y + (m + 9) \ 12) \ 4 + 275 * m\ 9 + d - 730531.5 + h / 24;

}

Is there some reason why you can't write your own function to do that? I've never heard of this.

The code is borrowed and I dont exactly know what all values are but I think it takes time input and output days (with decimals) from the year 2000.

If you have a solution for replacing this code, you are welcome.
other ways I'd like to know what the eqvivalent math function is.

\ is a divider that divides float and deliver a rounded integer

Some languages had the backslash as a modulo operator (occam was one), but I've never heard of it used like this.

yes I checked the modulo operator but taught is was the wrong function. maybe I've misunderstood the operator ** in my code, it is by calculations I've figured out.

To do what you want:

int n = 9;
int d = 2;

int r = roundedDivision(n, d);

int roundedDivision(int n, int d)
{
   float r1 = (float)n / (float)d;
   int r2 = n / d;

   r1 -= r2;
   if(r1 >= 0.5)
      r2++;

   return r2;
}
return 367 * y - 7 * (y + (m + 9) \ 12) \ 4 + 275 * m\ 9 + d - 730531.5 + h / 24;

The "" operator is used in .NET to force an integer division. In C/C++ it depends on the type of the arguments. If both sides are int's the compiler will use int math rather than float.

A rewrite could be as follows:

return 367 * y - 7 * lround(y + lround(m + 9) / 12) / 4 +lround( 275 * m)/ 9 + d - 730531.5 + h / 24;

Edit:

This would not agree with what you wrote in your first post ...

9/2 = 4.5
9\2 = 5

as 9\2 would be 4 - which I would assume is what you want.

The code looks like an extract from date calculations and I trust you will find plenty of alternative sources for the same functionality in "proper" C if you google for it (the Arduino timer library may be a good start).

thank you very much for your effort, both of you.

PaulS: your code works perfect but as BenF stated, I was wrong.

BenF: It sound like you know exactly what I'm after! I tried your code but it didn't give me the right value. but then I might discovered something:

float val_1;
float val_2;

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);
  
}

void loop() {
  
  val_1 = 1/3;                   //  this should now contain 0.3333333 ?
  val_2 = val_1 * 100;      //   0.3333333 * 100 = 33.33333
 
Serial.print("val_1: ");     //  val_1 = 0.00   ??
Serial.println(val_1);
Serial.print("val_2: ");  
Serial.println(val_2);

delay (90000);

}

what have I done wrong?

  val_1 = 1/3;                   //  this should now contain 0.3333333 ?
  val_2 = val_1 * 100;      //   0.3333333 * 100 = 33.33333

The is the same "rule" as above - two ints forces int math. If you change to this -

  val_1 = 1.0/3;
  val_2 = val_1 * 100;      //   0.3333333 * 100 = 33.33333
  • you should be ok.

The issues you face here are also the underlying reasons why Microsoft decided on separate operators in .NET for int "" and float "/" division. The choice of int vs. float is explicitly defined and easier to debug.

okey, lesson learned! (I almost started thinking that the arduino was tired...turned out to be me)

the problem with my function still remains, it doesn't work.
I have values on everything so it shouldn't be that hard to figure out how the math should be.

float FNday(int year,int month,int day,float hour){ 

return 367 * year - 7 * (year + (month + 9) \ 12) \ 4 + 275 * month\ 9 + day - 730531.5 + hour / 24;

}

int year = 2001;   
int month = 3;
int day = 4;
float hour = 15;
int mins = 30;

hour= hour + mins/60.0;  // hour = 15.5

d = FNday(year, month, day, hour);    //right value d = 428.14853
367 * 2001 - 7 * (2001 + (3 + 9) \ 12) \ 4 + 275 * 3\ 9 + 4 - 730531.5 + 15.5 / 24 = 428.14583

(I've heard that there could be a static error of +0.5 or -0.5 (don't remember the sign) but that could be added / subtracted later)

now it works!

the error was caused by the multiplying at the beginning

367 * 2001 = 13471 (totally wrong)

367.0 * 2001 = 734367 (correct)

so the same problem with dividing was applied to multiplying

from now on I will add a dot to every value I have :smiley:

thanks for the help!

Actually, the problems are not at all the same. The integer multiplication overflowed. The float multiplication did not.

The integer multiplication returned an integer. The float multiplication returned a float. A float is bigger than an integer.

okey so the overflow is causing the error!

god you cleared things out :slight_smile:

A float is bigger than an integer

A long is an integer :wink:

I'm wondering where this came from:

A long is an integer

I said that a float was bigger than an int. I wrote a little code to dump sizes:

void setup()
{
  Serial.begin(9600);
  Serial.println("Sizes");
  Serial.print("int: "); Serial.println(sizeof(int));
  Serial.print("float: "); Serial.println(sizeof(float));
  Serial.print("double: "); Serial.println(sizeof(double));
  Serial.print("long: "); Serial.println(sizeof(long));
  Serial.print("char: "); Serial.println(sizeof(char));
  Serial.print("byte: "); Serial.println(sizeof(byte));
  Serial.print("boolean: "); Serial.println(sizeof(boolean));
}

The output:

Sizes
int: 2
float: 4
double: 4
long: 4
char: 1
byte: 1
boolean: 1

So, a float IS bigger than an int. I know that a long is an int, but I don't see what that has to do with the issue that OP was discussing.

I'm wondering where this came from:
Quote:
A long is an integer

I said that a float was bigger than an int.

No you didn't.
Re-read reply #11. :wink:

It is quite dangerous to say that an "int" is bigger than a "float"; it is processor-dependant. An "int" in C++ on your PC is probably the same width as a "float".

I know that a long is an int,

:o

This is what I said in # 11:

Actually, the problems are not at all the same. The integer multiplication overflowed. The float multiplication did not.

The integer multiplication returned an integer. The float multiplication returned a float. A float is bigger than an integer.

I agree that the size of an int is processor dependent. However, this forum concerns itself primarily with a single family of processors, and on those processors, a float IS larger than an int.

Anyway, to be technically accurate, what I meant to say was the the range of values that can be stored in a float on an Arduino Duemilanove (had to go look at the board to figure out how to spell that) is larger than the range of values that can be stored in an int.

A float on the A/D has a range from -3.4028235E+38 to 3.4028235E+38. An int has a range from -32,768 to 32,767.

OP's multiplication example (367 * 2001) computed a value of 734367 which overflowed the int.

Sorry, maybe I was being a little flippant, but it is well worth remembering about type sizes, particularly if you're mixing Processing (where an "int" is 32 bits and a "long" is 64 bits) and the Arduino's Wiring (where an "int" is 16 bits and a "long" is 32 bits).
A calculation prototyped in Processing may well work and yet cause much head-scratching when ported onto an Arduino.

A calculation prototyped in Processing may well work and yet cause much head-scratching when ported onto an Arduino.

Good point. I will try to keep that in mind in any future discussion of types sizes.