Strange constant behavior - why?

it's nothing magic or arbitrarily..

There a couple of predefined operators, these are:

for integer division:

int operator /(int x, int y);

uint operator /(uint x, uint y);

long operator /(long x, long y);

ulong operator /(ulong x, ulong y);

for floating point division:

float operator /(float x, float y);

double operator /(double x, double y);

and for decimal division:

decimal operator /(decimal x, decimal y);

now, quite frankly, when the compiler detects a division in code, it somehow

has to decide which one it takes to perform the division.

The exact algorithm is pretty complicated and is explained in the C#

language reference at Section 7.4.2

if we simplify it, it comes down to

1) if there is an exactly fitting operator, take that.

2) if thats not possible take the one that requires the least amount of

implicit conversion

if it's not possible to find a match with implicit conversions there is no

match possible, and a compile time error will occur.

implicit conversions are conversion that do not lose any information, and

thus can be performed automatically by the compiler, examples are

int -> long

int -> float

float -> double

int -> double

now, if you have 29.7 / 21 the following happens:

there is no division operator that takes a float and a int, so the compilers

needs to convert one of the values..

you can't implicitly convert from float -> int, but you can convert from

int -> float, so the compiler uses the float division operator, which

returns a float value

if you have 297 / 210 it will use the integer division operator, so the

result will be an int, hence the wrong result..

now, as mentioned you can add .0 behind every number so it's an float for

sure, but there is a more precise way

In C# there are numeric suffixes defined

1L for 1 in long (can be mixed case, so 1l is allowed as well);

1UL for 1 in unsigned long (can be mixed case and other orde, so 1lu is

allowed as well)

1f for 1.0 in float

1d for 1.0 in double

1m for 1,00 in decimal

a integer number without suffix will be treated as an int unless the number

doesn't fit in 32 bits

a floating point number without suffix will be treated as an single (I dont

know what happens when the precision is better in double, since that is

usually the case)

damn, i'm long winded :-(

Ah well, really off to bed now..

Willem

Quote:

> I am using a constant to define a page height to width ratio, and I'm

> getting a very strange result in one case. Can anyone explain this?

> // for letter-size pages, returns 1.294

> const float PageRatio = (float)(11 / 8.5);

> // for A4-size pages, returns 1.414

> const float PageRatio = (float)(29.7 / 21);

> // My original construction for A4-size pages... returns 1!

> const float PageRatio = (float)(297 / 210);

> The first two work fine, the third one assigns a value of 1. Since

> 29.7/21 (centimeters) is the same as 297/210 (millimeters), shouldn't

> both of these work? Is this a bug or some subtlety I've missed?

> --

> | James Gifford - Nitrosyncretic Press |

> | http://www.nitrosyncretic.com for the Heinlein FAQ & more |