Discussion:
[omniORB] bug in CORBA::Fixed constructor
Luke Deller
2006-12-14 12:21:48 UTC
Permalink
Hi,

In omniORB (v4.1), the CORBA::Fixed constructor skips leading and
trailing zeros when constructing a fixed-point value from a string.
CORBA.fixed('0123d').precision() # should be 4
3
CORBA.fixed('12.340d').decimals() # should be 3
2

The code in corbaFixed.cc seems to do this quite deliberately, but I
think it is wrong:

Both the C++ and Python language mappings describe this string argument
with the phrase "the string representation of a fixed-point literal".
The CORBA specification (v2.6, sec 3.9.2) gives specific examples of
fixed-point literals, illustrating that leading and trailing zeroes are
significant.

Regards,
Luke.

**********************************************************************************************

Important Note
This email (including any attachments) contains information which is
confidential and may be subject to legal privilege. If you are not
the intended recipient you must not use, distribute or copy this
email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this
email are not necessarily the views of XPlan Technology.

It is the duty of the recipient to virus scan and otherwise test the
information provided before loading onto any computer system.
Xplan Technology does not warrant that the
information is free of a virus or any other defect or error.
**********************************************************************************************
Duncan Grisby
2006-12-29 01:15:39 UTC
Permalink
Post by Luke Deller
In omniORB (v4.1), the CORBA::Fixed constructor skips leading and
trailing zeros when constructing a fixed-point value from a string.
CORBA.fixed('0123d').precision() # should be 4
3
CORBA.fixed('12.340d').decimals() # should be 3
2
The code in corbaFixed.cc seems to do this quite deliberately, but I
The thing is, that despite the name, CORBA::Fixed in C++ and CORBA.fixed
in Python are actually decimal floating point. It doesn't make any sense
to maintain leading and trailing zeros in a floating point number. How
would the precision and decimals behave during arithmetic if leading and
trailing zeros were maintained? The supposed rules in the IDL
specification don't actually say what to do, only state the obvious
about what the maximum digits and scale values can be.

In C++, you get specific types generated for fixed declarations in IDL,
and they do maintain the digits and scale they are declared to have
(although that's optional according to the C++ mapping). The Python
mapping doesn't have equivalent generated types.
Post by Luke Deller
Both the C++ and Python language mappings describe this string argument
with the phrase "the string representation of a fixed-point literal".
The CORBA specification (v2.6, sec 3.9.2) gives specific examples of
fixed-point literals, illustrating that leading and trailing zeroes are
significant.
I think that bit of the spec is inconsistent with the other parts that
describe how fixed literals get involved in arithmetic, and with the
details of the language mappings. Fixed point is generally very badly
specified in all the CORBA specs.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Luke Deller
2007-01-02 10:37:45 UTC
Permalink
Thanks Duncan for your responses. Since my original post I have learned
that omniORB's behaviour in this regard corresponds to CORBA versions
prior
to CORBA 2.5. There was a change made in 2.5 making leading and
trailing
zeros in fixed point literals to be significant. The discussion that
led to
this change is documented here:
http://www.omg.org/issues/issue3581.txt

Two earlier discussions in which Michi Henning brought this up without
success:
http://www.omg.org/issues/issue1068.txt
http://www.omg.org/issues/issue1667.txt
Post by Duncan Grisby
The thing is, that despite the name, CORBA::Fixed in C++ and
CORBA.fixed
Post by Duncan Grisby
in Python are actually decimal floating point.
Yes, with regards to arithmetic. However I think it is fair to call the
corresponding IDL types "fixed-point", because the precision and scale
are
defined in the IDL type (and thus GIOP represents fixed-point values as
a
mantissa only without including the scale or precision). They would map
to
proper fixed point types in a language which has such types (eg Ada?)
Post by Duncan Grisby
It doesn't make any sense to maintain leading and trailing zeros in a
floating point number. How would the precision and decimals behave
during
Post by Duncan Grisby
arithmetic if leading and trailing zeros were maintained? The
supposed
Post by Duncan Grisby
rules in the IDL specification don't actually say what to do, only
state
Post by Duncan Grisby
the obvious about what the maximum digits and scale values can be.
I'm not so concerned about the behaviour of arithmetic here. The issue
is maintaining correct IDL types.

Here's an example which I think illustrates the problem:

==== blah.idl ===
module blah {
typedef fixed<5,2> Money;
const Money fifty_cents = 000.50d;
};
==== end blah.idl ===
Post by Duncan Grisby
import blah
blah.fifty_cents.decimals()
1

This should be 2 because blah::fifty_cents is of type Money which is
defined as fixed<5,2>. Similarly I'd want to construct values like this
at runtime
using the appropriate constructor.

As for arithmetic, both the Java class "java.math.BigDecimal" and the
Python
class "decimal.Decimal" do floating-point decimal arithmetic which
maintains
Post by Duncan Grisby
from decimal import Decimal
Decimal("1.10")*Decimal("1.10")
Decimal("1.2100")

So apparently maintaining trailing zeros through arithmetic like this
makes
sense to some people. Personally I can't see the use of this behaviour
in
arithmetic so I'm not going to argue with you that it makes sense :-)
The rules of arithmetic can be well-defined though.
Post by Duncan Grisby
I think that bit of the spec is inconsistent with the other parts that
describe how fixed literals get involved in arithmetic, and with the
details of the language mappings. Fixed point is generally very badly
specified in all the CORBA specs.
Yes, I've noticed that fixed point in general does seem poorly thought
out
in the CORBA specs. What in particular are you referring to as an
inconsistency here? I can't see why significant trailing and leading
zeros
in string literals couldn't be implemented consistently with the spec.

Thanks for your patience in reading this far :-)
Luke.


**********************************************************************************************

Important Note
This email (including any attachments) contains information which is
confidential and may be subject to legal privilege. If you are not
the intended recipient you must not use, distribute or copy this
email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this
email are not necessarily the views of XPlan Technology.

It is the duty of the recipient to virus scan and otherwise test the
information provided before loading onto any computer system.
Xplan Technology does not warrant that the
information is free of a virus or any other defect or error.
**********************************************************************************************
OKeeffe, Michael K
2007-01-04 00:34:58 UTC
Permalink
[snip]
As for arithmetic, both the Java class "java.math.BigDecimal" and the
Python
class "decimal.Decimal" do floating-point decimal arithmetic which
maintains
Post by Duncan Grisby
from decimal import Decimal
Decimal("1.10")*Decimal("1.10")
Decimal("1.2100")
So apparently maintaining trailing zeros through arithmetic like this
makes
sense to some people. Personally I can't see the use of this behaviour
in
arithmetic so I'm not going to argue with you that it makes sense :-)
Here are a few reasons:
http://www2.hursley.ibm.com/decimal/decifaq1.html#tzeros
Post by Duncan Grisby
I think that bit of the spec is inconsistent with the other
parts that
Post by Duncan Grisby
describe how fixed literals get involved in arithmetic, and with the
details of the language mappings. Fixed point is generally very badly
specified in all the CORBA specs.
Yes, I've noticed that fixed point in general does seem poorly thought
out
in the CORBA specs. What in particular are you referring to as an
inconsistency here? I can't see why significant trailing and leading
zeros
in string literals couldn't be implemented consistently with the spec.
Your BigDecimal example gives a hint that that it's poorly thought out
elsewhere besides the CORBA spec. The java class was not part of the
standard Java types (Integer, Float, Long), it was probably tacked on
later (and revised for Java 1.5), in a separate package (math), that
only includes BigDecimal and BigInteger! Further, from the Hursley link
above you'll find a link to the *revised* IEEE 754 spec, which covers
binary floating-point arithmetic.

The paper below which gives a few examples of why a floating scale is
advantageous over fixed, and also some of the historical aspects such as
some of the original machines used decimal arithmetic, but von Neummann
was behind the move to binary arithmetic for simplicity.

http://www2.hursley.ibm.com/decimal/IEEE-cowlishaw-arith16.pdf
Luke Deller
2007-01-04 06:20:32 UTC
Permalink
...
Post by OKeeffe, Michael K
Post by Luke Deller
from decimal import Decimal
Decimal("1.10")*Decimal("1.10")
Decimal("1.2100")
So apparently maintaining trailing zeros through arithmetic like
this
Post by OKeeffe, Michael K
Post by Luke Deller
makes sense to some people. Personally I can't see the use of this
behaviour in arithmetic so I'm not going to argue with you that it
makes sense :-)
http://www2.hursley.ibm.com/decimal/decifaq1.html#tzeros
That's a nice link. I'm still unable to argue why 1.10*1.10 should
be 1.2100 rather than 1.21, except by appealing to efficiency
(which is the last point on the list at your link). The extra precision
in the product is not required to express precision of measurement,
because the measurement was only precise to three significant figures,
not five. In other examples (such as 1.11*1.11), the product needs
extra precision than the multiplicands if we want to avoid rounding,
but this is not the case for 1.10*1.10.

Luke.

**********************************************************************************************

Important Note
This email (including any attachments) contains information which is
confidential and may be subject to legal privilege. If you are not
the intended recipient you must not use, distribute or copy this
email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this
email are not necessarily the views of XPlan Technology.

It is the duty of the recipient to virus scan and otherwise test the
information provided before loading onto any computer system.
Xplan Technology does not warrant that the
information is free of a virus or any other defect or error.
**********************************************************************************************
Alexander Haarer
2007-01-05 16:43:52 UTC
Permalink
Skipped content of type multipart/alternative-------------- next part --------------
A non-text attachment was scrubbed...
Name: alexander.haarer.vcf
Type: text/x-vcard
Size: 131 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20070105/73c2a413/alexander.haarer.vcf
OKeeffe, Michael K
2007-01-09 01:20:19 UTC
Permalink
Alexander Haarer writes:


1.10*1.10 => 1.2100

suggests, that the precision of the result would be higher than the
precision
of the source values - but this is just wrong, because the relative
errors
of the source values sum up in a multiplication operation.

That means the relative error of the result is always bigger. Following
the argumentation of the mentioned web link, this should result in less
significant digits, but not in more significant digits.

Personally, i dont like the style of enconding precision into digits,
because
it restricts to discrete steps of precision values.

IMO, most other reasons in the web link are only valid if user
presentation
requirements and internal data representation requirements are mixed up.
(which IMO is bad idea)


Alexander,

Yes, that's a good point. I see I wasn't addressing Luke's specific
example, more the basic question of where trailing zeros are useful.

I think the link below (and example adding 1 and 0.001) explains their
reasoning: the idea is to treat the calculation as exact:

"Given that an addition operator does not know whether a number is a
measurement or an exact quantity then it has no option other than to
return the exact answer (the fourth case). How this result is
interpreted is up to the application, and that application is at liberty
to apply some rounding rule or to treat the result as exact, as
appropriate.

So, default operations must treat calculations as exact. "

There's the reasoning, but I'd agree with your point, that if it is
exact, I should have to specify that, i.e. "1.000", or "1".setExact().
It seems they have it defaulting the wrong way - another example is in
Java you have the option of:

decimalVal1.multiply(decimalVal2).stripTrailingZeros();

Where I should have to specify "keepTrailingZeros()" instead.

http://www2.hursley.ibm.com/decimal/decifaq4.html#signif
<http://www2.hursley.ibm.com/decimal/decifaq4.html#signif>

Well, I will say it's not perfect, but better than it was, see Kahan's
page here for some funny tricks Excel, Java, Matlab, and even compilers
can play:
http://www.cs.berkeley.edu/~wkahan/






-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20070108/3ce9a1a3/attachment.htm
Jonathan Biggar
2007-01-10 00:39:45 UTC
Permalink
Post by OKeeffe, Michael K
1.10*1.10 => 1.2100
suggests, that the precision of the result would be higher than the
precision
of the source values - but this is just wrong, because the relative errors
of the source values sum up in a multiplication operation.
That means the relative error of the result is always bigger. Following
the argumentation of the mentioned web link, this should result in less
significant digits, but not in more significant digits.
Personally, i dont like the style of enconding precision into digits,
because
it restricts to discrete steps of precision values.
You're presuming that precision equals relative error. That may be true
in some use cases, but not all. In other use cases, 1.10 may be exact
and the result of 1.10*1.10 should be exactly 1.2100.

For use cases where relative error is important, you can use the
rounding and/or truncation functions to trim the result.
--
Jon Biggar
Levanta
***@levanta.com
650-403-7252
Continue reading on narkive:
Loading...