By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,617 Members | 1,792 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,617 IT Pros & Developers. It's quick & easy.

12.34f vs (float) 12.34

P: n/a
Is there a difference between a constant like "12.34f" and "(float)
12.34"?

In principle, at least, the latter is a double constant being cast to
a float; while the two both generate actual constants, does the latter
ACTUALLY do a conversion at compile time? That is, are there constants
where

<constant>f != (float) <constant>

?

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 15 '05 #1
Share this Question
Share on Google+
19 Replies


P: n/a
No. The compiler will optimize the cast away assuming it can. It's probably
generating something like this:

private static void Blah()
..locals (float V_0, float V_1)
L_0000: ldc.r4 1.23
L_0001: stloc.0
L_0002: ldc.r4 4.56
L_0003: stloc.1

from this:

static void Blah()
{
float f1 = 1.23F;
float f2 = (float) 4.56;
}
--
____________________
Klaus H. Probst, MVP
http://www.vbbox.com/
"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
Is there a difference between a constant like "12.34f" and "(float)
12.34"?

In principle, at least, the latter is a double constant being cast to
a float; while the two both generate actual constants, does the latter
ACTUALLY do a conversion at compile time? That is, are there constants
where

<constant>f != (float) <constant>

?

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 15 '05 #2

P: n/a
"Klaus H. Probst" wrote:
No. The compiler will optimize the cast away assuming it can. It's probably
generating something like this:

private static void Blah()
.locals (float V_0, float V_1)
L_0000: ldc.r4 1.23
L_0001: stloc.0
L_0002: ldc.r4 4.56
L_0003: stloc.1

from this:

static void Blah()
{
float f1 = 1.23F;
float f2 = (float) 4.56;
}


Indeed it is. The question, though, was HOW it's optimizing the cast
away, whether code like "1.23f" and "(float) 1.23" might ever generate
slightly different constants.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 15 '05 #3

P: n/a
The answers to those two questions are:

HOW: it's called constant folding, and is performed by the C# compiler, and
there's loads of information out there, and
WHETHER: in theory I think they could in your example (but that's just my
interpretation); section 11.1.3 of the CLI docs states:

"Storage locations for floating point numbers (statics, array elements, and
fields of classes) are of fixed size. The supported storage sizes are
float32 and float64. Everywhere else (on the evaluation stack, as arguments,
as return types, and as local variables) floating point numbers are
represented using an internal floating-point type. In each such instance,
the nominal type of the variable or expression is either R4 or R8, but its
value may be represented internally with additional range and/or precision.
The size of the internal floating-point representation is
implementation-dependent, may vary, and shall have precision at least as
great as that of the variable or expression being represented."

From my experience the internal representation can differ between debug and
release.

Hope that helps, but please don't take my answer as gospel.

Stu

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
"Klaus H. Probst" wrote:
No. The compiler will optimize the cast away assuming it can. It's probably generating something like this:

private static void Blah()
.locals (float V_0, float V_1)
L_0000: ldc.r4 1.23
L_0001: stloc.0
L_0002: ldc.r4 4.56
L_0003: stloc.1

from this:

static void Blah()
{
float f1 = 1.23F;
float f2 = (float) 4.56;
}


Indeed it is. The question, though, was HOW it's optimizing the cast
away, whether code like "1.23f" and "(float) 1.23" might ever generate
slightly different constants.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 15 '05 #4

P: n/a
Stu Smith wrote:
HOW: it's called constant folding,
Yes, thanks. Point of my question, though, is that I can imagine a few
ways that this might be done:

* Very straightforwardly, whereby "(float) 1.23" constructs a double
value 1.23, then casts it to a single.

* More convolutedly, whereby the constant folding operation sees the
(float) cast being applied to an implicitly typed double, and goes
back to the literal and reparses it as 1.23f.

* Complex parsing, where cast followed by a literal parses the literal
exactly as if it were 1.23f.

The point being that in some cases the first approach might yield
slightly different values than the first.
WHETHER: in theory I think they could in your example (but that's just my
interpretation); section 11.1.3 of the CLI docs states:


I'm not sure that ECMA-335 has much to say about the workings of the
compiler ....

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 15 '05 #5

P: n/a
"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
Stu Smith wrote:
HOW: it's called constant folding,
Yes, thanks. Point of my question, though, is that I can imagine a few
ways that this might be done:

* Very straightforwardly, whereby "(float) 1.23" constructs a double
value 1.23, then casts it to a single.

* More convolutedly, whereby the constant folding operation sees the
(float) cast being applied to an implicitly typed double, and goes
back to the literal and reparses it as 1.23f.

* Complex parsing, where cast followed by a literal parses the literal
exactly as if it were 1.23f.


As far as I'm aware (and we're at the limits of my knowledge here), constant
folding is done at compile time, so option one is out of the question. I
believe the compiler makes passes over the statement/expression trees it has
generated, looking for certain patterns, and replacing them with
equivalents. I guess one pattern could be something like "(builtin value
type) constant -> new constant".

The point being that in some cases the first approach might yield
slightly different values than the first.
WHETHER: in theory I think they could in your example (but that's just my interpretation); section 11.1.3 of the CLI docs states:
I'm not sure that ECMA-335 has much to say about the workings of the
compiler ....


Don't know about that, but I do know that if you have a variable of type
float it's not guaranteed to be no more than a float.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 15 '05 #6

P: n/a
Stu Smith wrote:
* Very straightforwardly, whereby "(float) 1.23" constructs a double
value 1.23, then casts it to a single.
As far as I'm aware (and we're at the limits of my knowledge here), constant
folding is done at compile time, so option one is out of the question.


We're pretty much at the limits of my knowledge, too. I've written a
simple compiler, so I have some knowledge of the issues involved, but
that's about it.

But I don't see why you say that option 1 can be ruled out? Seems to
me: Parser sees a stream of digits followed by a . and another stream
of digits which is NOT followed by one of {d, f, m}. Bingo: a double
constant for the parse tree. Optimizer later comes along and sees the
expression cast(float, double constant) and does a compile-time cast,
reducing it to a float constant.

* * *

I suppose I should just do the brute force thing: write a simple test
program to generate reams of float constants, and see if (say)
2.22222222222222f != (float) 2.22222222222222.

Course, I'll probably find more than I care to know about method size
limits ....

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 15 '05 #7

P: n/a

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
Stu Smith wrote:
* Very straightforwardly, whereby "(float) 1.23" constructs a double
value 1.23, then casts it to a single.
As far as I'm aware (and we're at the limits of my knowledge here),
constant folding is done at compile time, so option one is out of the question.


We're pretty much at the limits of my knowledge, too. I've written a
simple compiler, so I have some knowledge of the issues involved, but
that's about it.

But I don't see why you say that option 1 can be ruled out? Seems to
me: Parser sees a stream of digits followed by a . and another stream
of digits which is NOT followed by one of {d, f, m}. Bingo: a double
constant for the parse tree. Optimizer later comes along and sees the
expression cast(float, double constant) and does a compile-time cast,
reducing it to a float constant.


I thought you meant a run-time cast. Not sure whether you'd call
compile-time folding a cast but I think we're talking the same thing, even
if we use different words.

* * *

I suppose I should just do the brute force thing: write a simple test
program to generate reams of float constants, and see if (say)
2.22222222222222f != (float) 2.22222222222222.
And what I meant about having extra precision was something like this:

class Foo
{
public void Test()
{
float localFloat = _memberFloat;

// The following doesn't have to be true, ie assertion could fire.
Debug.Assert( _memberFloat == localFloat );
}

private float _memberFloat = 1.23;
}

Course, I'll probably find more than I care to know about method size
limits ....

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 15 '05 #8

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #9

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #10

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #11

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #12

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #13

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #14

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #15

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #16

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #17

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #18

P: n/a
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least
jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double
to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs
Nov 16 '05 #19

P: n/a
The C# compiler will act the same way on ALL platforms.
The JIT will not.
The MSIL should be all the same regardless of the CPU or the OS you're
compiling under.

About the conversion - you can check out what does the C# compiler spits out
with the ILDASM utility.
Located in the .NET Framework SDK folder.

Cheers,
Branimir
--
Branimir Giurov
MCSD.NET, MCDBA
eAgility LLC

"Jon Shemitz" <jo*@midnightbeach.com> wrote in message
news:40***************@midnightbeach.com...
cody wrote:
Is there a difference between a constant like "12.34f" and "(float)
12.34"?


You can be sure that both are evaluated to compile time contants (at least jit time).
But you cannot assume that 12.34f ==(float)12.34 because conversion double to float might result in loss of precision.


Right. This is pretty much where I ended up. Even if the canonical
(MS) C# compiler works this way on a Pentium, that is not to say that
all C# compilers on all processors will act this way.

--

programmer, author http://www.midnightbeach.com
and father http://www.midnightbeach.com/hs

Nov 16 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.