Issue 1667: Proposal on floating point fixes (orb_revision) Source: (, ) Nature: Uncategorized Issue Severity: Summary: Summary: I"m preparing a proposal to "fix" fixed point types, but I"d like to outline what I am thinking before I have it completed, in order to give people a chance to comment. Michi has pointed out a few issues with the fixed point constant grammar, but I think I can resolve those pretty easily by making changes so that fixed point constants are only allowed to be defined using the syntax: const fixed FOO = 1.2D; Some people have expressed the idea that the fixed point type specification is lacking sufficient semantic content, and they are afraid that since different languages or even implementations of languages might do the math differently that portability or interoperability is affected. Frankly, I don"t see the problem as serious for the CORE RTF. In most cases, the fixed point type is mapped to the native fixed point facility of the language. If that isn"t sufficiently robust to support stuff like banking applications, the CORE RTF can"t do much to fix it anyway. For the C++ RTF: For the C++ binding, of course, things are broken. However, I think I may have a solution to the problem: First, define a new class CORBA::FixedValue which is used as the results of all of the Fixed arithmetic operations, as well as for the type for fixed point constants. FixedValue would store the digits and scale information dynamically. All of the defined fixed point types would be convertable from/to the FixedValue type, with the DATA_CONVERSION exception available to signal overflow. Second, get rid of the explicit reference to a template type. Since the grammar will be changed to no longer allow anonymous fixed point declarations (as parameter types), there is no longer a specific need to define the exact type name for the Fixed types, and in fact, implementations no longer must implement fixed as a template type. Resolution: Revised Text: Actions taken: July 13, 1998: received issue July 15, 1998: closed issue -- resolved by issue754 July 15, 1998: closed issue; Duplicate or Merged Discussion: End of Annotations:===== Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 15:30:41 -0700 From: Jonathan Biggar To: Steve Vinoski , michi@dstc.edu.au, orb_revision@omg.org, cxx_revision@omg.org Subject: Ideas on floating point fixes References: <199807101802.OAA22482@boston.iona.ie> <199807101939.PAA25274@boston.iona.ie> I'm preparing a proposal to "fix" fixed point types, but I'd like to outline what I am thinking before I have it completed, in order to give people a chance to comment. Just to give you an idea what I am thinking: For the CORE RTF: I'm still not sure why people think that the core definitions for fixed are a real problem. As far as I can tell, the specification seems solid enough to implement (at least for the IDL compiler). The only change I think needs to be made to not allow anonymous declarations of fixed point types, in order to solve the C++ mapping problems. Michi has pointed out a few issues with the fixed point constant grammar, but I think I can resolve those pretty easily by making changes so that fixed point constants are only allowed to be defined using the syntax: const fixed FOO = 1.2D; Some people have expressed the idea that the fixed point type specification is lacking sufficient semantic content, and they are afraid that since different languages or even implementations of languages might do the math differently that portability or interoperability is affected. Frankly, I don't see the problem as serious for the CORE RTF. In most cases, the fixed point type is mapped to the native fixed point facility of the language. If that isn't sufficiently robust to support stuff like banking applications, the CORE RTF can't do much to fix it anyway. For the C++ RTF: For the C++ binding, of course, things are broken. However, I think I may have a solution to the problem: First, define a new class CORBA::FixedValue which is used as the results of all of the Fixed arithmetic operations, as well as for the type for fixed point constants. FixedValue would store the digits and scale information dynamically. All of the defined fixed point types would be convertable from/to the FixedValue type, with the DATA_CONVERSION exception available to signal overflow. Second, get rid of the explicit reference to a template type. Since the grammar will be changed to no longer allow anonymous fixed point declarations (as parameter types), there is no longer a specific need to define the exact type name for the Fixed types, and in fact, implementations no longer must implement fixed as a template type. So, tell me what you think. Does this look like the right approach to solving the problem? -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 11:33:51 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > For the CORE RTF: > > I'm still not sure why people think that the core definitions for > fixed > are a real problem. As far as I can tell, the specification seems > solid > enough to implement (at least for the IDL compiler). The only > change I > think needs to be made to not allow anonymous declarations of fixed > point types, in order to solve the C++ mapping problems. > > Michi has pointed out a few issues with the fixed point constant > grammar, but I think I can resolve those pretty easily by making > changes > so that fixed point constants are only allowed to be defined using > the > syntax: > > const fixed FOO = 1.2D; One question: What is the type of this constant? Is it implicitly fixed<2,1>? So I could say const fixed FOO = 00001.1D; which would have type fixed<6,1>? I completely agree with the idea that forcing a typedef for fixed-point types is a good thing. That way, there are no anonymous fixed-point types. What about type compatibility though? (which really is not just a language mapping issue, IMO). Given the following const fixed FOO = 12345.67D; // Implicitly fixed<7,2>? typedef fixed<3,1> f3_1; typedef fixed<6,2> f6_2; typedef fixed<9,3> f9_3; typedef fixed<9,1> f9_1; interface bar { void op(in f3_1 p1, in f6_2 p2, in f9_3 p3, in f9_1 p4); }; Can I call op() like this? op(FOO, FOO, FOO, FOO); If this call is legal, will the "chopped-off" fractional part be rounded or truncated? > Some people have expressed the idea that the fixed point type > specification is lacking sufficient semantic content, and they are > afraid that since different languages or even implementations of > languages might do the math differently that portability or > interoperability is affected. Frankly, I don't see the problem as > serious for the CORE RTF. In most cases, the fixed point type is > mapped > to the native fixed point facility of the language. If that isn't > sufficiently robust to support stuff like banking applications, the > CORE > RTF can't do much to fix it anyway. Yes, but for those languages without a built-in fixed-point facility, there must be precise rules for how to emulate the computational semantics. Without that, computations on different platforms will yield different results. > For the C++ RTF: > > For the C++ binding, of course, things are broken. However, I think > I > may have a solution to the problem: > > First, define a new class CORBA::FixedValue which is used as the > results > of all of the Fixed arithmetic operations, as well as for the type > for > fixed point constants. FixedValue would store the digits and scale > information dynamically. All of the defined fixed point types would > be > convertable from/to the FixedValue type, with the DATA_CONVERSION > exception available to signal overflow. In principle, that sounds like the right approach to me. However, the rules are again important. Does Ada have rules we can lift for mixed fixed-point computations? > Second, get rid of the explicit reference to a template type. Since the > grammar will be changed to no longer allow anonymous fixed point > declarations (as parameter types), there is no longer a specific need to > define the exact type name for the Fixed types, and in fact, > implementations no longer must implement fixed as a template type. Sounds good to me. I think we need to have coercion rules that raise exceptions at run time if I, for example, try to return a fixed-point value from an operation that won't fit into the return type (because its magnitude is too large, for example). Also, I suspect that explicit coercion functions need to be there, so I get control over rounding/truncation if I need to coerce a generic value into a particular type. > So, tell me what you think. Does this look like the right approach to > solving the problem? I think that's the right approach in principle. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 18:51:35 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > > On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > > For the CORE RTF: > > > > I'm still not sure why people think that the core definitions for > fixed > > are a real problem. As far as I can tell, the specification seems > solid > > enough to implement (at least for the IDL compiler). The only > change I > > think needs to be made to not allow anonymous declarations of > fixed > > point types, in order to solve the C++ mapping problems. > > > > Michi has pointed out a few issues with the fixed point constant > > grammar, but I think I can resolve those pretty easily by making > changes > > so that fixed point constants are only allowed to be defined using > the > > syntax: > > > > const fixed FOO = 1.2D; > > One question: What is the type of this constant? Is it implicitly > fixed<2,1>? Yes. > So I could say > > const fixed FOO = 00001.1D; > > which would have type fixed<6,1>? No, the text is quite clear that leading AND trailing zeros are stripped off, so the type of this is also implicitly fixed<6,1>. > I completely agree with the idea that forcing a typedef for fixed-point > types is a good thing. That way, there are no anonymous fixed-point types. > > What about type compatibility though? (which really is not just a language > mapping issue, IMO). Given the following > > const fixed FOO = 12345.67D; // Implicitly fixed<7,2>? > > typedef fixed<3,1> f3_1; > typedef fixed<6,2> f6_2; > typedef fixed<9,3> f9_3; > typedef fixed<9,1> f9_1; > > interface bar { > void op(in f3_1 p1, in f6_2 p2, in f9_3 p3, in f9_1 p4); > }; > > Can I call op() like this? > > op(FOO, FOO, FOO, FOO); This is unltimately a language binding issue. My COBOL is quite rusty, but my understanding of Java, Smalltalk and Ada suggest that this is more or less legal in all of these languages (ignoring overflow for p1 and p2). With the new FixedValue class, we can also make it legal in C++. > If this call is legal, will the "chopped-off" fractional part be rounded > or truncated? Each language will have its own mechanism for overflow detection and rounding vs truncation. If a programmer needs cross-lingual consistency, he may have to do some additional work. > > Some people have expressed the idea that the fixed point type > > specification is lacking sufficient semantic content, and they are > > afraid that since different languages or even implementations of > > languages might do the math differently that portability or > > interoperability is affected. Frankly, I don't see the problem as > > serious for the CORE RTF. In most cases, the fixed point type is > mapped > > to the native fixed point facility of the language. If that isn't > > sufficiently robust to support stuff like banking applications, > the CORE > > RTF can't do much to fix it anyway. > > Yes, but for those languages without a built-in fixed-point > facility, there > must be precise rules for how to emulate the computational > semantics. > Without that, computations on different platforms will yield > different > results. This is pretty much just C and C++. We can define the math for these languages as precisely as we want. Actually, the part of the spec definining how arithmetic works for IDL fixed point constants, although not rigorous, is adequate to guide implementation. > > For the C++ RTF: > > > > For the C++ binding, of course, things are broken. However, I > think I > > may have a solution to the problem: > > > > First, define a new class CORBA::FixedValue which is used as the > results > > of all of the Fixed arithmetic operations, as well as for the type > for > > fixed point constants. FixedValue would store the digits and > scale > > information dynamically. All of the defined fixed point types > would be > > convertable from/to the FixedValue type, with the DATA_CONVERSION > > exception available to signal overflow. > > In principle, that sounds like the right approach to me. However, > the > rules are again important. Does Ada have rules we can lift for mixed > fixed-point computations? Yes, they should be adequate. > > Second, get rid of the explicit reference to a template type. Since the > > grammar will be changed to no longer allow anonymous fixed point > > declarations (as parameter types), there is no longer a specific need to > > define the exact type name for the Fixed types, and in fact, > > implementations no longer must implement fixed as a template type. > > Sounds good to me. I think we need to have coercion rules that raise > exceptions at run time if I, for example, try to return a fixed-point > value from an operation that won't fit into the return type (because its > magnitude is too large, for example). Also, I suspect that explicit > coercion functions need to be there, so I get control over rounding/truncation > if I need to coerce a generic value into a particular type. Sure, we can define the generic coersion to be truncation towards zero, and provide a round function: FixedValue round(const FixedValue &val, short digits, short scale); to round properly. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 12:11:45 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > > const fixed FOO = 1.2D; > > > > One question: What is the type of this constant? Is it implicitly > fixed<2,1>? > > Yes. > > > So I could say > > > > const fixed FOO = 00001.1D; > > > > which would have type fixed<6,1>? > > No, the text is quite clear that leading AND trailing zeros are > stripped > off, so the type of this is also implicitly fixed<6,1>. ^^^^^^^^^^ >From your words, I think you meant to say fixed<2,1>? If so, I would consider this unacceptable, because I could not ever define a fixed-point constant with value zero that has a type other than fixed<1,1>: const fixed FOO = 0.0D; // Implicitly fixed<1,1> const fixed FOO = 0000.0000D; // Implicitly fixed<1,1> :-( Why strip the leading and trailing zeros? If I bother to write them, surely I have a reason, namely that they are significant for the digits and scale? > > Can I call op() like this? > > > > op(FOO, FOO, FOO, FOO); > > This is unltimately a language binding issue. My COBOL is quite > rusty, > but my understanding of Java, Smalltalk and Ada suggest that this is > more or less legal in all of these languages (ignoring overflow for > p1 > and p2). With the new FixedValue class, we can also make it legal > in > C++. I'm not sure it's entirely a language mapping issue. At the very least, I would expect that all language mappings would use the same rules for compatibility, otherwise I cannot write IDL safely. For example: const fixed FOO = 1.3D; // Implicitly fixed<2,1> const fixed BAR = 12345.678; // Implicitly fixed<8,3> interface I { typedef fixed<4,2> xxx; void compute(in xxx p1, in xxx p2); }; If the rules are not clear, I may write the above IDL in the expectation that it will be possible to call compute(FOO, BAR); However, if not all language bindings guarantee that this will work, the IDL will not be implementable in all languages. > > If this call is legal, will the "chopped-off" fractional part be rounded > > or truncated? > > Each language will have its own mechanism for overflow detection and > rounding vs truncation. If a programmer needs cross-lingual > consistency, he may have to do some additional work. Again, I don't like this, because it destroys the language transparency of CORBA. I should not have to care whether the server is implemented in Ada or in C++. With language-specific truncation/rounding rules, the same client can send the same value to different instances of the same interface but different values may get delivered to the object implementations. > This is pretty much just C and C++. We can define the math for these > languages as precisely as we want. Actually, the part of the spec > definining how arithmetic works for IDL fixed point constants, although > not rigorous, is adequate to guide implementation. I'm not sure whether what is there is sufficient. Regardless of whether it is sufficient or not, I'd feel a lot more comfortable with something more rigorous, such as the Ada spec. > > In principle, that sounds like the right approach to me. However, the > > rules are again important. Does Ada have rules we can lift for mixed > > fixed-point computations? > > Yes, they should be adequate. Then let's lift 'em ;-) > Sure, we can define the generic coersion to be truncation towards zero, > and provide a round function: > > FixedValue round(const FixedValue &val, short digits, short scale); > > to round properly. Is it that simple? There are several rounding algorithms around. For example, in Australia, 1 and 2 cent coins were abolished some years ago. When you buy something in a shop, the normal rounding algorithm does *not* apply ("normal" rounding would round amounts of 1.01 and 1.02 to 1.00, and 1.03 and 1.04 to 1.05). However, the normal rounding algorithm can be used to cheat, so the rules are actually different. I've forgotten the details, but from memory, 1.04 is actually rounded to 1.00, not 1.05. I'm not sure how relevant this is to the above. You could argue that this is an application-specific problem. I just threw this in to point out that numeric stuff always tends to be more complicated than first meets the eye. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Date: Fri, 10 Jul 1998 19:29:24 PDT Sender: Bill Janssen From: Bill Janssen To: Jonathan Biggar , Michi Henning Subject: Re: Ideas on floating point fixes CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org References: Excerpts from local.omg: 10-Jul-98 Re: Ideas on floating point.. Michi Henning@dstc.edu.a (4175*) > const fixed FOO = 12345.67D; // Implicitly fixed<7,2>? > typedef fixed<3,1> f3_1; > typedef fixed<6,2> f6_2; > typedef fixed<9,3> f9_3; > typedef fixed<9,1> f9_1; Why not simply disallow anonymous fixed types for constants, too? That is, force the constant declaration to be of a particular fixed type: const f6_2 FOO = 1234.67; Doesn't that solve a number of the problems at once? You also don't need fancy syntax for the literal; the type of the constant will allow you to do the right thing. Bill Return-Path: Date: Fri, 10 Jul 1998 19:30:54 PDT Sender: Bill Janssen From: Bill Janssen To: Jonathan Biggar , Michi Henning Subject: Re: Ideas on floating point fixes CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org References: Excerpts from local.omg: 10-Jul-98 Re: Ideas on floating point.. Michi Henning@dstc.edu.a (4175*) > I completely agree with the idea that forcing a typedef for fixed-point > types is a good thing. That way, there are no anonymous fixed-point types. Yes, good idea. Bill Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 12:36:08 +1000 (EST) From: Michi Henning To: Bill Janssen cc: Jonathan Biggar , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Bill Janssen wrote: > Why not simply disallow anonymous fixed types for constants, too? That > is, force the constant declaration to be of a particular fixed type: > > const f6_2 FOO = 1234.67; > > Doesn't that solve a number of the problems at once? You also don't > need fancy syntax for the literal; the type of the constant will allow > you to do the right thing. That is the solution I favor myself. There cannot be any ambiguity this way -- every constant has a well-defined type, and that type cannot be anonymous. The only thing we then need to define is what happens if the literal won't fit: const f6_2 FOO = 1.123456789D; // ?? const f6_2 FOO = 1234567.89D; // ?? Given that we are dealing with *compile-time* constant expressions in all cases, I would be inclined to simply flag this as a compilation error. It gets a bit harder though if expressions are involved: const f6_2 FOO = 9999.9D; const f6_2 BAR = 9999.9D; const f6_2 X = FOO * BAR; // Whoops, won't fit. Coerce or error? I don't know what the right thing is in this case. I was hoping that the Ada model would deliver some inspiration there (I have to admit, I haven't read it yet). The above expression example can be extended to other pathological cases, such as loss of fractional digits. Is that an error, or will be coerced? If coerced, will it use truncation or rounding? Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Date: Fri, 10 Jul 1998 19:42:05 PDT Sender: Bill Janssen From: Bill Janssen To: Bill Janssen , Michi Henning Subject: Re: Ideas on floating point fixes CC: Jonathan Biggar , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org References: Excerpts from direct: 10-Jul-98 Re: Ideas on floating point.. Michi Henning@dstc.edu.a (1640*) > Given that we are dealing with *compile-time* constant expressions in all > cases, I would be inclined to simply flag this as a compilation error. > It gets a bit harder though if expressions are involved: > const f6_2 FOO = 9999.9D; > const f6_2 BAR = 9999.9D; > const f6_2 X = FOO * BAR; // Whoops, won't fit. Coerce or error? > I don't know what the right thing is in this case. I was hoping that the > Ada model would deliver some inspiration there (I have to admit, I haven't > read it yet). Since we don't have operational semantics for these things, I'd be inclined to just disallow expressions of them. My fallback postion would choose Error. What do we do with const unsigned long FOO = 0xFFFFFFFF * 0xFFFFFFFF; Coerce or error? Bill Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 12:46:19 +1000 (EST) From: Michi Henning To: Bill Janssen cc: Jonathan Biggar , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Bill Janssen wrote: > Since we don't have operational semantics for these things, I'd be > inclined to just disallow expressions of them. My fallback postion > would choose Error. > > What do we do with > > const unsigned long FOO = 0xFFFFFFFF * 0xFFFFFFFF; > > Coerce or error? The spec says "it is an error". Pretty meaningless statement though, because that doesn't oblige the compiler to emit a diagnostic, or otherwise state what behavior should result. In the absence of a definition for "is an error", you have to assume the behavior is implementation-dependent. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 20:03:54 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > > > So I could say > > > > > > const fixed FOO = 00001.1D; > > > > > > which would have type fixed<6,1>? > > > > No, the text is quite clear that leading AND trailing zeros are > stripped > > off, so the type of this is also implicitly fixed<6,1>. > ^^^^^^^^^^ > > >From your words, I think you meant to say fixed<2,1>? Right. > If so, I would consider this unacceptable, because I could not ever > define a fixed-point constant with value zero that has a type other > than fixed<1,1>: > > const fixed FOO = 0.0D; // Implicitly fixed<1,1> > const fixed FOO = 0000.0000D; // Implicitly fixed<1,1> :-( > > Why strip the leading and trailing zeros? If I bother to write them, > surely I have a reason, namely that they are significant for the > digits and scale? You are getting stuck on something that shouldn't be a problem. The only reason for defining the implicit digits and scale for a fixed point constant is to define what the IDL compiler does with arithmetic for fixed point constants. I belive that is well defined enough to be implementable. It really doesn't matter whether you write: const fixed FOO = 1.0D; or const fixed FOO = 1.000D; because: const fixed BAR = 2.0D * FOO; will have the same result anyway. > > > Can I call op() like this? > > > > > > op(FOO, FOO, FOO, FOO); > > > > This is unltimately a language binding issue. My COBOL is quite > rusty, > > but my understanding of Java, Smalltalk and Ada suggest that this > is > > more or less legal in all of these languages (ignoring overflow > for p1 > > and p2). With the new FixedValue class, we can also make it legal > in > > C++. > > I'm not sure it's entirely a language mapping issue. At the very > least, > I would expect that all language mappings would use the same rules > for > compatibility, otherwise I cannot write IDL safely. For example: > > const fixed FOO = 1.3D; // Implicitly fixed<2,1> > const fixed BAR = 12345.678; // Implicitly fixed<8,3> > > interface I { > typedef fixed<4,2> xxx; > void compute(in xxx p1, in xxx p2); > }; > > If the rules are not clear, I may write the above IDL in the > expectation > that it will be possible to call > > compute(FOO, BAR); > > However, if not all language bindings guarantee that this will work, > the IDL will not be implementable in all languages. Every language that supports fixed natively will support your argument p1, although you might have to write an explicit type coersion in Ada. For p2, you have an overflow. In some languages overflows might raise exceptions, and in others in might truncate in some fashion. I think it is more important to map fixed to the native language facility rather than try to solve these cases in the ORB core. > > > If this call is legal, will the "chopped-off" fractional part be rounded > > > or truncated? > > > > Each language will have its own mechanism for overflow detection and > > rounding vs truncation. If a programmer needs cross-lingual > > consistency, he may have to do some additional work. > > Again, I don't like this, because it destroys the language transparency > of CORBA. I should not have to care whether the server is implemented > in Ada or in C++. With language-specific truncation/rounding rules, > the same client can send the same value to different instances of the > same interface but different values may get delivered to the object > implementations. You don't have to care! It is up to the programmer in the particular language to use the native fixed point capability to get the semantics he wants. We simply can't dictate one semantic for fixed point types in face of the entrenched capability of the target language! > > This is pretty much just C and C++. We can define the math for these > > languages as precisely as we want. Actually, the part of the spec > > definining how arithmetic works for IDL fixed point constants, although > > not rigorous, is adequate to guide implementation. > > I'm not sure whether what is there is sufficient. Regardless of whether it > is sufficient or not, I'd feel a lot more comfortable with something more > rigorous, such as the Ada spec. > > > > In principle, that sounds like the right approach to me. However, the > > > rules are again important. Does Ada have rules we can lift for mixed > > > fixed-point computations? > > > > Yes, they should be adequate. > > Then let's lift 'em ;-) > > > Sure, we can define the generic coersion to be truncation towards zero, > > and provide a round function: > > > > FixedValue round(const FixedValue &val, short digits, short scale); > > > > to round properly. > > Is it that simple? There are several rounding algorithms around. For example, > in Australia, 1 and 2 cent coins were abolished some years ago. When you > buy something in a shop, the normal rounding algorithm does *not* apply > ("normal" rounding would round amounts of 1.01 and 1.02 to 1.00, > and 1.03 and 1.04 to 1.05). However, the normal rounding algorithm can > be used to cheat, so the rules are actually different. I've forgotten > the details, but from memory, 1.04 is actually rounded to 1.00, not 1.05. > > I'm not sure how relevant this is to the above. You could argue that > this is an application-specific problem. I just threw this in to point > out that numeric stuff always tends to be more complicated than first > meets the eye. And I do so argue. :-) -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 20:05:45 -0700 From: Jonathan Biggar To: Michi Henning CC: Bill Janssen , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > > On Fri, 10 Jul 1998, Bill Janssen wrote: > > > Why not simply disallow anonymous fixed types for constants, too? > That > > is, force the constant declaration to be of a particular fixed > type: > > > > const f6_2 FOO = 1234.67; > > > > Doesn't that solve a number of the problems at once? You also > don't > > need fancy syntax for the literal; the type of the constant will > allow > > you to do the right thing. > > That is the solution I favor myself. There cannot be any ambiguity > this way -- > every constant has a well-defined type, and that type cannot be > anonymous. > The only thing we then need to define is what happens if the literal > won't > fit: > > const f6_2 FOO = 1.123456789D; // ?? > const f6_2 FOO = 1234567.89D; // ?? > > Given that we are dealing with *compile-time* constant expressions > in all > cases, I would be inclined to simply flag this as a compilation > error. > It gets a bit harder though if expressions are involved: > > const f6_2 FOO = 9999.9D; > const f6_2 BAR = 9999.9D; > const f6_2 X = FOO * BAR; // Whoops, won't fit. Coerce > or error? > > I don't know what the right thing is in this case. I was hoping that > the > Ada model would deliver some inspiration there (I have to admit, I > haven't > read it yet). > > The above expression example can be extended to other pathological > cases, > such as loss of fractional digits. Is that an error, or will be > coerced? > If coerced, will it use truncation or rounding? The proposal I am writing up requires that the IDL compiler truncate (towards zero) on the right, and treat overflow as a compilation error. If someone desparately needs rounding in his IDL source, he can just do the math himself and stick the value in there! -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 20:08:27 -0700 From: Jonathan Biggar To: Bill Janssen CC: Michi Henning , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Bill Janssen wrote: > > Excerpts from direct: 10-Jul-98 Re: Ideas on floating point.. Michi > Henning@dstc.edu.a (1640*) > > > Given that we are dealing with *compile-time* constant expressions > in all > > cases, I would be inclined to simply flag this as a compilation > error. > > It gets a bit harder though if expressions are involved: > > > const f6_2 FOO = 9999.9D; > > const f6_2 BAR = 9999.9D; > > const f6_2 X = FOO * BAR; // Whoops, won't fit. Coerce > or error? > > > I don't know what the right thing is in this case. I was hoping > that the > > Ada model would deliver some inspiration there (I have to admit, I > haven't > > read it yet). > > Since we don't have operational semantics for these things, I'd be > inclined to just disallow expressions of them. My fallback postion > would choose Error. > > What do we do with > > const unsigned long FOO = 0xFFFFFFFF * 0xFFFFFFFF; > > Coerce or error? The spec already says that this is an error. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 13:12:41 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Bill Janssen , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > const f6_2 FOO = 9999.9D; > > const f6_2 BAR = 9999.9D; > > const f6_2 X = FOO * BAR; // Whoops, won't > fit. Coerce or error? > > > > I don't know what the right thing is in this case. I was hoping > that the > > Ada model would deliver some inspiration there (I have to admit, I > haven't > > read it yet). > > > > The above expression example can be extended to other pathological > cases, > > such as loss of fractional digits. Is that an error, or will be > coerced? > > If coerced, will it use truncation or rounding? > > The proposal I am writing up requires that the IDL compiler truncate > (towards zero) on the right, and treat overflow as a compilation > error. > If someone desparately needs rounding in his IDL source, he can just > do > the math himself and stick the value in there! Given that we are exclusively dealing with compile-time constant expressions, that sounds fair to me. We just have to make sure that all IDL compilers come up with the same value. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Date: Fri, 10 Jul 1998 20:26:13 PDT Sender: Bill Janssen From: Bill Janssen To: Bill Janssen , Michi Henning Subject: Re: Ideas on floating point fixes CC: Jonathan Biggar , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org References: Excerpts from direct: 10-Jul-98 Re: Ideas on floating point.. Michi Henning@dstc.edu.a (851*) > The spec says "it is an error". Pretty meaningless statement though, because > that doesn't oblige the compiler to emit a diagnostic, or otherwise state > what behavior should result. Whoa! That's kind of hard-nosed, Michi. Saying "it is an error" seems to me a quite reasonable and unambiguous statement that a conforming compiler must generate an error and refuse to accept the offending IDL. Bill Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 13:30:33 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > You are getting stuck on something that shouldn't be a problem. The > only reason for defining the implicit digits and scale for a fixed > point > constant is to define what the IDL compiler does with arithmetic for > fixed point constants. I belive that is well defined enough to be > implementable. It really doesn't matter whether you write: > > const fixed FOO = 1.0D; > > or > > const fixed FOO = 1.000D; > > because: > > const fixed BAR = 2.0D * FOO; > > will have the same result anyway. I think your previous proposal fixes this nicely. If all fixed point constants must have a definite type, the problem can't arise. As you say, the only implicit typing then is for literals, so we know how to do computation: const fixed<4,1> FOO = 100.1D; const fixed<6,2> BAR = FOO * 9.99999D; // Coerce by truncation I think that would be best. > > > Each language will have its own mechanism for overflow detection and > > > rounding vs truncation. If a programmer needs cross-lingual > > > consistency, he may have to do some additional work. > > > > Again, I don't like this, because it destroys the language transparency > > of CORBA. I should not have to care whether the server is implemented > > in Ada or in C++. With language-specific truncation/rounding rules, > > the same client can send the same value to different instances of the > > same interface but different values may get delivered to the object > > implementations. > > You don't have to care! It is up to the programmer in the particular > language to use the native fixed point capability to get the semantics > he wants. We simply can't dictate one semantic for fixed point types in > face of the entrenched capability of the target language! That's a strong argument, at least for those languages that have built-in fixed-point support. We are getting bitten yet again by the least-common denominator problem, of course: it is hard to add things to IDL that don't easily map to different implementation languages. In light of that, it may well have been better to never introduce a fixed-point type at all. For example, you could exchange fixed-point values simply as strings: typedef string fixed_3_2; // fixed<3,2> interface foo { fixed_3_2 compute(in fixed_3_2 p1, in fixed_3_2 p2); }; Now we have achieved exactly what we are trying to do now: The semantics of the fixed-point types are language-specific. For languages without fixed-point support, you simply use floating point to do the computation instead. To return a value of the correct type, the server simply does the equivalent of sprintf(buf, "%.2f", value) and sends the value back as a string. Sounds like that would be nearly as good as what we will end up with once we have gone through the huge pain of fixing this mess. Makes me wonder whether fixed-point *really* was ever necessary, especially when you consider that you can transmit fixed-point as long double without loss of precision... :-( interface foo { long double compute(in long double p1, in long double p2); }; Each sender and receiver can then deal with the value internally as a fixed value to its heart's content, and no-one has to bother with fixed-point types... Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 13:49:50 +1000 (EST) From: Michi Henning To: Bill Janssen cc: Jonathan Biggar , Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Bill Janssen wrote: > Excerpts from direct: 10-Jul-98 Re: Ideas on floating point.. Michi > Henning@dstc.edu.a (851*) > > > The spec says "it is an error". Pretty meaningless statement > though, because > > that doesn't oblige the compiler to emit a diagnostic, or > otherwise state > > what behavior should result. > > Whoa! That's kind of hard-nosed, Michi. Saying "it is an error" > seems > to me a quite reasonable and unambiguous statement that a conforming > compiler must generate an error and refuse to accept the offending > IDL. No, not at all. It says "it is an error", no more, no less. For example, - It could mean that the IDL is in error, because I have made a mistake. - It could mean that an erroneous value may be generated. - It could mean that there will be an error if I use the value later. - It could mean that the compiler will flag it as an error. - It could mean the compiler could generate code that produces an error when I compile it. - It could mean that the compiler could generate code that produces an error at run time by generating a trap. Nowhere can I find a statement such as "a compiler must generate a compile-time diagnostic" or some such. The problem really is that "it is an error" says nothing other than that a construct is malformed in some way. It implies nothing about behavior. If you don't believe me, try the following with a number of IDL compilers: const long l = 99 << 128; According to the spec, this "is an error". I know of only one IDL compiler that actually generates a diagnostic in this case... Of course, the spec only says that shifting by more than 64 is an error, so you have to assume that shifting a short by 30 bits is perfectly sensible for some reason, as is shifting a long by 40 bits: const short l = 99 << 30; // Legal IDL const long l = 99 << 40; // Legal IDL At least the second definition used to be illegal, until the addition of long long broke this... It now is perfectly OK to shift longs by 40 bits, even though up to CORBA 2.1, it was not... And just to make everyone happy, shifting by zero bits is quite OK too: const short s = 33 << 0; // Nothing wrong with this This is almost certainly a semantic error on part of the IDL author, because we are dealing with compile-time constant expressions. However, because shifting a value by zero bits at run time is legal in C, it automatically follows that this must make sense for IDL as well, sigh... Of course, you could do it like the ANSI specs. They are careful to define things like "implementation-defined", "implementation-dependent", and "undefined", and they use words such as "shall", that have a defined meaning. But then, vendors could no longer pile whatever they like into their IDL compiler as extensions and still claim that it conforms to CORBA. You see, we need something that is a standard that everyone can conform to, but that still allows everyone to do what they like, so it is better that "it is an error"... :-( Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Date: Fri, 10 Jul 1998 20:53:56 PDT Sender: Bill Janssen From: Bill Janssen To: Jonathan Biggar , Michi Henning Subject: Re: Ideas on floating point fixes CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org References: Excerpts from local.omg: 10-Jul-98 Re: Ideas on floating point.. Michi Henning@dstc.edu.a (3508*) > Makes me wonder > whether fixed-point *really* was ever necessary, especially when you > consider that you can transmit fixed-point as long double without > loss > of precision... :-( I've got to agree that the limited variant of fixed-point in the CORBA spec is rather painful, but the functionality of precise numbers is important. We generalized CORBA `fixed' for HTTP-NG, to allow for arbitrary denominators (for those folks who'd like to count thirds by 1/3s and/or (Xeroxism showing here) reams) instead of just decimal denominators such as hundredths, thousandths, millions, etc. And the numerator is a bounded bignum (that is, an arbitrarily large integer range). That works so nicely that I dumped all of the pre-defined integer types, since they can all be expressed as fixed-point types (denominator of 1, appropriate min-numerator and max-numerator values). We just released a draft of the HTTP-ng architecture document, which describes the type system. It's at http://www.w3.org/TR/WD-HTTP-NG-architecture See section 3.5.1. Bill Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 21:09:21 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > > On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > > You are getting stuck on something that shouldn't be a problem. > The > > only reason for defining the implicit digits and scale for a fixed > point > > constant is to define what the IDL compiler does with arithmetic > for > > fixed point constants. I belive that is well defined enough to be > > implementable. It really doesn't matter whether you write: > > > > const fixed FOO = 1.0D; > > > > or > > > > const fixed FOO = 1.000D; > > > > because: > > > > const fixed BAR = 2.0D * FOO; > > > > will have the same result anyway. > > I think your previous proposal fixes this nicely. If all fixed point > constants must have a definite type, the problem can't arise. As you > say, > the only implicit typing then is for literals, so we know how to do > computation: > > const fixed<4,1> FOO = 100.1D; > > const fixed<6,2> BAR = FOO * 9.99999D; // Coerce by > truncation > > I think that would be best. I've backed away from that, simply because it is unnecessary. For now, I plan to leave the generic "fixed" declaration for fixed constants, because it works fine. I'm planning to remove the from the , of course. > > > > Each language will have its own mechanism for overflow detection and > > > > rounding vs truncation. If a programmer needs cross-lingual > > > > consistency, he may have to do some additional work. > > > > > > Again, I don't like this, because it destroys the language transparency > > > of CORBA. I should not have to care whether the server is implemented > > > in Ada or in C++. With language-specific truncation/rounding rules, > > > the same client can send the same value to different instances of the > > > same interface but different values may get delivered to the object > > > implementations. > > > > You don't have to care! It is up to the programmer in the particular > > language to use the native fixed point capability to get the semantics > > he wants. We simply can't dictate one semantic for fixed point types in > > face of the entrenched capability of the target language! > > That's a strong argument, at least for those languages that have built-in > fixed-point support. We are getting bitten yet again by the least-common > denominator problem, of course: it is hard to add things to IDL that don't > easily map to different implementation languages. In light of that, > it may well have been better to never introduce a fixed-point type at all. > For example, you could exchange fixed-point values simply as strings: > > typedef string fixed_3_2; // fixed<3,2> > > interface foo { > fixed_3_2 compute(in fixed_3_2 p1, in fixed_3_2 p2); > }; > > Now we have achieved exactly what we are trying to do now. I think we ought to have fixed point in IDL for the same reason that they finally added bool to C++: because if it isn't standard, then everyone will invent 100 different incompatible fixed-point mechanisms. > The semantics of the fixed-point types are language-specific. For languages > without fixed-point support, you simply use floating point to do the > computation instead. To return a value of the correct type, the server > simply does the equivalent of sprintf(buf, "%.2f", value) and sends > the value back as a string. > > Sounds like that would be nearly as good as what we will end up with once > we have gone through the huge pain of fixing this mess. Makes me wonder > whether fixed-point *really* was ever necessary, especially when you > consider that you can transmit fixed-point as long double without loss > of precision... :-( > > interface foo { > long double compute(in long double p1, in long double p2); > }; > > Each sender and receiver can then deal with the value internally as a > fixed value to its heart's content, and no-one has to bother with > fixed-point types... Not true. Try to store 1.0/100.0 in a long double some time and then convert it back and see what you get! Long double simply doesn't have the right arithmetic properties to do decimal math correctly. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 14:30:36 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > I think your previous proposal fixes this nicely. If all fixed point > > constants must have a definite type, the problem can't arise. As you say, > > the only implicit typing then is for literals, so we know how to do > > computation: > > > > const fixed<4,1> FOO = 100.1D; > > > > const fixed<6,2> BAR = FOO * 9.99999D; // Coerce by truncation > > > > I think that would be best. > > I've backed away from that, simply because it is unnecessary. For now, > I plan to leave the generic "fixed" declaration for fixed constants, > because it works fine. I'm planning to remove the > from the , of course. OK. I think that can be made to work. But now we need language-specific rules for how these constants get a type in the target language. For example, in C++, we would get: // IDL const fixed FOO = 1.1D; // C++ const Fixed<1,1> FOO = 1.1; That of course gets us back to the anonymous type problem (now the constant has anonymous type). It also would mean that I really cannot have a constant with value zero and type fixed<6,2>. On the other hand, if in C++ we have a generic fixed-point type instead of template types, it would become something like: // C++ const Fixed FOO = 1.1; The question then is, where do the digits and scale come from? They would have to come from the value, because there is nothing else. Slight problem if the constant requires high precision, but also must have an integral value: // IDL const fixed FOO = 1.00000D; // I *really* would like this to // be fixed<6,5> What will the type of this constant be in C++, whether we use a generic or specific fixed-point class? // C++ const Fixed<1,1> FOO = 1.0; // OR: const Fixed FOO = 1.0; Either way, the precision is lost. I'm still having a feeling that throwing trailing and leading zeros away is problematic as soon as implicit typing is used. Maybe it would be best to have a three-parameter constructor in C++ for a generic type: // C++ const Fixed FOO(1, 1, 1.0); This explicitly sets digits, scale, and value. At least this makes it possible to preserve the typing information from the IDL (whether leading and trailing zeros are ignored is then an orthogonal issue). > > Each sender and receiver can then deal with the value internally as a > > fixed value to its heart's content, and no-one has to bother with > > fixed-point types... > > Not true. Try to store 1.0/100.0 in a long double some time and then > convert it back and see what you get! Long double simply doesn't have > the right arithmetic properties to do decimal math correctly. You are right, of course. My apologies for being facetious -- it's not been a good day for me so far... Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 21:56:05 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > > On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > > > I think your previous proposal fixes this nicely. If all fixed > point > > > constants must have a definite type, the problem can't arise. As > you say, > > > the only implicit typing then is for literals, so we know how to > do > > > computation: > > > > > > const fixed<4,1> FOO = 100.1D; > > > > > > const fixed<6,2> BAR = FOO * 9.99999D; // Coerce by > truncation > > > > > > I think that would be best. > > > > I've backed away from that, simply because it is unnecessary. For > now, > > I plan to leave the generic "fixed" declaration for fixed > constants, > > because it works fine. I'm planning to remove the > > > from the , of course. > > OK. I think that can be made to work. But now we need > language-specific > rules for how these constants get a type in the target language. > For example, in C++, we would get: > > // IDL > const fixed FOO = 1.1D; > > // C++ > const Fixed<1,1> FOO = 1.1; > > That of course gets us back to the anonymous type problem (now the > constant > has anonymous type). It also would mean that I really cannot have a > constant with value zero and type fixed<6,2>. > > On the other hand, if in C++ we have a generic fixed-point type > instead > of template types, it would become something like: > > // C++ > const Fixed FOO = 1.1; Yes, I'm planning to have a generic C++ Fixed type to resolve the problem with things like the fact that the results of math operations need run time calculations of digits & scale. > The question then is, where do the digits and scale come from? They would > have to come from the value, because there is nothing else. You probably need to declare this as: const Fixed FOO = "1.1"; in order to avoid problems with floating point representation of decimal values. > Slight problem if the constant requires high precision, but also must > have an integral value: > > // IDL > const fixed FOO = 1.00000D; // I *really* would like this to > // be fixed<6,5> Michi, I keep trying to explain. Whether you write the constant as 1.0D or 1.00000D makes no difference. When you use it as an argument to an arithmetic operator, you will get exactly the same result either way! > What will the type of this constant be in C++, whether we use a > generic or specific fixed-point class? > > // C++ > const Fixed<1,1> FOO = 1.0; > > // OR: > const Fixed FOO = 1.0; > > Either way, the precision is lost. I'm still having a feeling that > throwing trailing and leading zeros away is problematic as soon as > implicit typing is used. > > Maybe it would be best to have a three-parameter constructor in C++ > for a > generic type: > > // C++ > const Fixed FOO(1, 1, 1.0); > > This explicitly sets digits, scale, and value. At least this makes > it > possible to preserve the typing information from the IDL (whether > leading > and trailing zeros are ignored is then an orthogonal issue). For constants it doesn't matter. Initialize them from a string representation of the constant value, and use the same algorithm as the IDL compiler to assign an implicit digits and scale. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 15:57:03 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > The question then is, where do the digits and scale come from? They would > > have to come from the value, because there is nothing else. > > You probably need to declare this as: > > const Fixed FOO = "1.1"; > > in order to avoid problems with floating point representation of decimal > values. That sounds sensible. Digits, scale, and value are all visible here. I like this better than the three-argument constructor I suggested earlier, because the initialization I suggested does not deal with imprecise floating-point representation of certain values, but your string initialization handles this correctly. > > Slight problem if the constant requires high precision, but also must > > have an integral value: > > > > // IDL > > const fixed FOO = 1.00000D; // I *really* would like this to > > // be fixed<6,5> > > Michi, I keep trying to explain. Whether you write the constant as 1.0D > or 1.00000D makes no difference. When you use it as an argument to an > arithmetic operator, you will get exactly the same result either way! Sorry, maybe I'm dense, but bear with me please. The type of the constant *is* important (look at the table on page 3-20 of the spec). Assume: const fixed FOO = 100.0;// fixed<4,1>, right? const fixed BAR = 3.0; // fixed<2,1> const fixed Q = FOO / BAR; The rules on page 3-10 say that the type of Q is: fixed<4 - 1 + 1 + Sinf, Sinf> Because the result is 33.33333333333333333333333333333 (31 digits), the type of Q therefore is fixed<31,27>. Now let's assume for a moment that we *would* preserve trailing zeros: const fixed FOO = 100.0; // fixed<4,1> const fixed BAR = 3.00000; // Assume fixed<6,5> for now const fixed Q = FOO / BAR; Now we get for Q: fixed<4 - 1 + 5 + Sinf, Sinf> I make that fixed<31,23> That's not the same as fixed<31,27>, which we get if we throw trailing zeros away. On the other hand, if we assume that the division results in something that doesn't produce a fraction, we get: const fixed FOO = 100.0;// fixed<4,1> const fixed BAR = 1.0; // fixed<1,1> const fixed Q = FOO / BAR; Now the type of Q is fixed<4 - 1 + 1 + Sinf, Sinf> I make that fixed<4,1> Whereas if we assume that trailing zeros *are*, preserved it looks like this: const fixed FOO = 100.0; // fixed<4,1> const fixed BAR = 1.00000; // assume fixed<6,5> const fixed Q = FOO / BAR; Now the type of Q is: fixed<4 - 1 + 5 + Sinf, Sinf> Which is fixed<8,1> Again, that's not the same as fixed<4,1>. So, unless I'm misunderstanding something, throwing leading or trailing zeros away *does* have an influence on the type of the result. > For constants it doesn't matter. Initialize them from a string > representation of the constant value, and use the same algorithm as > the > IDL compiler to assign an implicit digits and scale. I agree. The initialization from a string representation is nice. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Fri, 10 Jul 1998 23:30:20 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > Sorry, maybe I'm dense, but bear with me please. The type of the > constant > *is* important (look at the table on page 3-20 of the spec). > > Assume: > > const fixed FOO = 100.0;// fixed<4,1>, right? > const fixed BAR = 3.0; // fixed<2,1> > const fixed Q = FOO / BAR; > > The rules on page 3-10 say that the type of Q is: > > fixed<4 - 1 + 1 + Sinf, Sinf> > > Because the result is 33.33333333333333333333333333333 (31 digits), > the type of Q therefore is fixed<31,27>. > > Now let's assume for a moment that we *would* preserve trailing > zeros: > > const fixed FOO = 100.0; // fixed<4,1> > const fixed BAR = 3.00000; // Assume fixed<6,5> for now > const fixed Q = FOO / BAR; > > Now we get for Q: > > fixed<4 - 1 + 5 + Sinf, Sinf> > > I make that > > fixed<31,23> > > That's not the same as fixed<31,27>, which we get if we throw > trailing zeros > away. True, but why would you want 33.333333333333333333333333333 when you can get 3.33333333333333333333333333333? :-) You are right. The rules in the table leave enough room for the maximum result, which would be 999.9D / .1D = 9999.999999999999999999999999999, which is fixed<31,27>. The best approach to fix this problem is to define that arithmetic operations are calculated using an intermediate result of up to 62 digits and then truncated to fit in 31 digits (or less). With this rule, you would always get fixed<31,29> from both versions of 100/3! > On the other hand, if we assume that the division results in something > that doesn't produce a fraction, we get: > > const fixed FOO = 100.0;// fixed<4,1> No, fixed<3,0>! > const fixed BAR = 1.0; // fixed<1,1> No, fixed<1,0>! > const fixed Q = FOO / BAR; > > Now the type of Q is > > fixed<4 - 1 + 1 + Sinf, Sinf> > > I make that > > fixed<4,1> No, fixed<3,0>! > Whereas if we assume that trailing zeros *are*, preserved it looks like > this: > > const fixed FOO = 100.0; // fixed<4,1> > const fixed BAR = 1.00000; // assume fixed<6,5> > const fixed Q = FOO / BAR; > > Now the type of Q is: > > fixed<4 - 1 + 5 + Sinf, Sinf> > > Which is > > fixed<8,1> > > Again, that's not the same as fixed<4,1>. In this case it is the same, since the 3rd paragraph of 3-21 states that you throw away leading and trailing zeros again, so both results are fixed<3,0>! > So, unless I'm misunderstanding something, throwing leading or trailing > zeros away *does* have an influence on the type of the result. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Sat, 11 Jul 1998 16:45:15 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Fri, 10 Jul 1998, Jonathan Biggar wrote: > > That's not the same as fixed<31,27>, which we get if we throw trailing zeros > > away. > > True, but why would you want 33.333333333333333333333333333 when you can > get 3.33333333333333333333333333333? :-) You are right. The rules in > the table leave enough room for the maximum result, which would be > 999.9D / .1D = > 9999.999999999999999999999999999, which is fixed<31,27>. > > The best approach to fix this problem is to define that arithmetic > operations are calculated using an intermediate result of up to 62 > digits and then truncated to fit in 31 digits (or less). With this > rule, you would always get fixed<31,29> from both versions of 100/3! Fine, that will make me happy :-) > In this case it is the same, since the 3rd paragraph of 3-21 states that > you throw away leading and trailing zeros again, so both results are > fixed<3,0>! OK, thanks for pointing this out! Just to throw another spanner in the works... ;-) I just stumbled across the following sentence on page 3-29 (last sentence of the para): The fixed data type represents a fixed-point decimal number of up to 31 significant digits. The scale factor is normally a non-negative integer less than or equal to the total number of digits (note that constants with effectively negative scale, such as 10000, are always permitted.). However, some languages and environments may be able to accommodate types that have a negative scale or a scale greater than the number of digits. My reading of this is that typedef fixed<10,-5> SomeType; may not be supported in all environments. If that is the case, then surely it can't be legal IDL? Also, the above seems to indicate that the following can be legal: typedef fixed<10,30> SomeOtherType; Again, I don't think this can be legal if only some environments will support it. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Sat, 11 Jul 1998 08:12:28 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , orb_revision@omg.org, cxx_revision@omg.org Subject: Re: Ideas on floating point fixes References: Michi Henning wrote: > Just to throw another spanner in the works... ;-) I just stumbled > across the following sentence on page 3-29 (last sentence of the > para): > > The fixed data type represents a fixed-point decimal number > of up to 31 significant digits. The scale factor is normally > a > non-negative integer less than or equal to the total number > of > digits (note that constants with effectively negative scale, > such as 10000, are always permitted.). However, some > languages > and environments may be able to accommodate types that have > a > negative scale or a scale greater than the number of digits. > > My reading of this is that > > typedef fixed<10,-5> SomeType; > > may not be supported in all environments. If that is the case, then > surely it can't be legal IDL? > > Also, the above seems to indicate that the following can be legal: > > typedef fixed<10,30> SomeOtherType; > > Again, I don't think this can be legal if only some environments > will > support it. Right. I'm planning on making both of these illegal because of portability problems. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Date: Mon, 13 Jul 1998 09:45:07 -0700 (PDT) From: Joachim Achtzehnter To: Michi Henning cc: cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Sat, 11 Jul 1998, Michi Henning wrote: > No, not at all. It says "it is an error", no more, no less. > For example, > > - It could mean that the IDL is in error, because I have > made a mistake. > > - It could mean that an erroneous value may be generated. > > - It could mean that there will be an error if I use the value > later. > > - It could mean that the compiler will flag it as an error. > > - It could mean the compiler could generate code that produces > an error when I compile it. > > - It could mean that the compiler could generate code that > produces an error at run time by generating a trap. > > Nowhere can I find a statement such as "a compiler must generate a > compile-time diagnostic" or some such. > > The problem really is that "it is an error" says nothing other than > that a construct is malformed in some way. It implies nothing about > behavior. True, but it is still an error, and anybody committing this error violates the spec. What you are discussing is a matter of convenience, i.e. whether the error is reported, but does not affect the semantics of conforming programs. Joachim -- joachim@kraut.bc.ca (http://www.kraut.bc.ca) joachim@mercury.bc.ca (http://www.mercury.bc.ca) Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Tue, 14 Jul 1998 07:25:42 +1000 (EST) From: Michi Henning To: Joachim Achtzehnter cc: cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Mon, 13 Jul 1998, Joachim Achtzehnter wrote: > > The problem really is that "it is an error" says nothing other than > > that a construct is malformed in some way. It implies nothing about > > behavior. > > True, but it is still an error, and anybody committing this error violates > the spec. What you are discussing is a matter of convenience, i.e. whether > the error is reported, but does not affect the semantics of conforming > programs. Yes. Fat lot of good that does me though if I expect the same IDL to work with different ORBs. I can't just go and compile my IDL to see whether it is correct. Instead, I have to compile it with *all* IDL compilers I intend to use, and even that still doesn't mean that the IDL is correct, only that it compiles with all of them. So, I have to grab the spec, read it, understand it, and then hand-parse my IDL and do my own semantic checks. A less than ideal situation, in my opinion. Last time I looked, if I compiled a C program with pretty much any compiler, it would also compile on any other C compiler (barring portability problems and header file differences). The situation is nowhere near as clear-cut for IDL, unfortunately. In IDL, I can't even rely on a compiler to tell me whether my IDL is syntactically correct, let alone semantically. Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Date: Mon, 13 Jul 1998 15:14:43 -0700 (PDT) From: Joachim Achtzehnter To: Michi Henning cc: cxx_revision@omg.org Subject: Re: Ideas on floating point fixes On Tue, 14 Jul 1998, Michi Henning wrote: > Last time I looked, if I compiled a C program with pretty much any > compiler, it would also compile on any other C compiler (barring > portability problems and header file differences). ...barring portability problems, eh? And would you make a similar statement about C++? Probably not. I have only seen bits and pieces of the FDIS and previous drafts, yet have encountered numerous statements to the effect that "implementations are not required to report this error". > The situation is nowhere near as clear-cut for IDL, unfortunately. In > IDL, I can't even rely on a compiler to tell me whether my IDL is > syntactically correct, let alone semantically. I am not disputing that a tool that validates compliance with the spec would be useful (wow, this term is beginning to follow me into my dreams :-), but I still see it as quite a separate issue, and the spec doesn't prevent anybody from writing such a tool. Joachim -- joachim@kraut.bc.ca (http://www.kraut.bc.ca) joachim@mercury.bc.ca (http://www.mercury.bc.ca)