Issue 1538: Missing text describing fixed point constant mapping (cxx_revision) Source: (, ) Nature: Revision Severity: Summary: Summary: There is no text in the C++ language mapping that describes how to map a fixed point constant declaration. Resolution: Revised Text: Actions taken: June 23, 1998: received issue February 23, 1999: closed issue Discussion: received issue End of Annotations:===== Return-Path: Sender: jon@floorboard.com Date: Mon, 22 Jun 1998 23:29:45 -0700 From: Jonathan Biggar To: cxx_revision@omg.org, issues@omg.org Subject: Missing text describing fixed point constant mapping There is no text in the C++ language mapping that describes how to map a fixed point constant declaration. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Mon, 20 Jul 1998 12:02:08 -0700 From: Jonathan Biggar To: cxx_revision@omg.org Subject: Proposal to "fix" fixed point in the C++ mapping :-) This proposal addresses the following issues: Issue 1056: Fixed types in orbos/98-01-11 Issue 1069: Typos on p 20-34 of orbos/98-01-11 Issue 1070: macros for fixed arithmetic results * Issue 1072: fixed_digits and fixed_scale member functions Issue 1073: Missing constructor for Fixed Issue 1092: C++ mapping for fixed is broken (01) * Issue 1093: C++ mapping for fixed is broken (02) Issue 1124: C++ Fixed type issue (01) Issue 1125: Fixed type (02) Issue 1126: C++ Fixed Type (03) Issue 1538: Missing text describing fixed point constant mapping Summary description of the problems with fixed: The worst problem with the existing CORBA 2.2 mapping for fixed point types is the attempted use of a template type with the digits and scale as template arguments. This causes two major problems, neither of which is possible to fix without reworking the mapping entirely. The first is that the Fixed is defined as a template in the CORBA namespace. This cannot be implemented in a compiler that does not support either namespaces or member templates. Since there are still quite a few compilers with this deficiency, this is a bad idea for a fundamental type. The second problem is that the arithmetic for fixed point types (particularly the divide operation) defines the digits and scale of the result of binary mathematics operations (+, -, *, /) to depend on the runtime values of the arguments. This cannot be expressed using C++ template declarations, since the digits and scale must be compile time constants. The second problem area with the fixed point mapping is that the mapping totally ignores fixed point constant declarations and how to map them into C++. For an IDL fixed point declaration: const fixed foo = 1.2D; neither the use of the keyword "fixed" without digits and scale parameters, nor the actual fixed point literal, "1.2D" have a mapping into C++. The third major problem area has to do with the IDL grammar itself. The CORBA 2.2 grammar allows fixed point types to be defined anonymously (without a typedef) as IDL operation parameters or return types. But since the C++ mapping specifies that _var and _out types are defined for anonymous fixed point types, this causes two problems: first, the mapping does not define how to handle a negative scale when determining the name for the _var and _out types for an anonymous fixed point type, and second, there is no clear place to define the _var and _out types when an anonymous fixed point type is used as an IDL parameter or return type. Overview of the Proposal: The key to the proposal is to redefine CORBA::Fixed to be a non-template type that can handle any combination of digits and scale at run time. All of the arithmetic operations are defined using CORBA::Fixed. However, this proposal does not require that CORBA::Fixed be used as the type for operation parameters and fields in IDL structured types (struct, union, sequence, array, etc). The reason for this is that a generic fixed point value needs about 18 bytes of storage, minimum--16 for the 31 digits plus sign, 2 for the digits and scale values. So, by allowing the implementation to choose to use another type for fixed point types with an explicit digits and scale, this gives the implementation the flexibility to reduce the storage cost for fixed point types in places where the digits and scale are known. It also allows the implementation to code the bounds check for digits and scale into the conversion between the "generic" CORBA::Fixed type and the actual type used for operation parameters and structured members, rather than having to add code at runtime to check these bounds inside the marshaling engine. In fact, an implementation could still use a template for these unnamed types without the problems described above, since the implementation is free to declare the template however it needs to. The second problem, that the mapping for fixed point constants is not specified, is solved by mapping fixed point constants to normal C++ string literals. The third problem, issues with declaring _out & _var types for fixed point has been mainly resolved by the ORB core RTF, which has already approved a fix that obviate the need for the C++ RTF to fix these problems. The proposal accepted by the core RTF are to forbid the declaration of anonymous fixed types as IDL operation parameters. In addition, the proposal presented here eliminates the _var type for fixed point types, because it is unnecessary. This proposal just treats C++ fixed point types like built-in C++ types. Since a maximal sized fixed point type needs little if any more storage than a long double, which is passed by value, there isn't much need to use dynamic storage (new and delete) for fixed point values. Besides, the C++ mapping specifies that fixed point types are always passed by reference, and never by pointer. The ORB core RTF has also passed a proposal that outlaws the use of a negative scale, since the original CORBA 2.2 specification stated that this was not portable anyway. Proposal: Make the following changes to the CORBA 2.2 C++ mapping (section 20): -------------------------------------------------------------------------------- Add the following paragraphs to the end of section 20.4: Fixed Point Constants Since C++ does not have a native fixed point type, IDL fixed point literals are mapped to C++ strings without the trailing 'd' or 'D' in order to guarantee that there is no loss of precision. For example, the IDL fixed point literal 123.456D is mapped to the C++ string "123.456". -------------------------------------------------------------------------------- Replace the entire text of section 20.11 with: The C++ mapping for fixed is defined by the following class: class Fixed { public: // Constructors... Fixed(int val = 0); Fixed(long val); Fixed(unsigned val); Fixed(unsigned long val); Fixed(Double val); Fixed(LongDouble val); Fixed(const Fixed& val); ~Fixed(); // Conversions... operator LongDouble() const; Fixed round(UShort digits, UShort scale) const; Fixed truncate(UShort digits, UShort scale) const; // Operators... Fixed& operator=(const Fixed& val); Fixed& operator+=(const Fixed& val); Fixed& operator-=(const Fixed& val); Fixed& operator*=(const Fixed& val); Fixed& operator/=(const Fixed& val); Fixed& operator++(); Fixed& operator++(int); Fixed& operator--(); Fixed& operator--(int); Fixed& operator+() const; Fixed& operator-() const; int operator!() const; // Other member functions UShort fixed_digits() const; UShort fixed_scale() const; }; istream& operator>>(istream& is, Fixed &val); ostream& operator<<(ostream& os, const Fixed &val); Fixed operator + (const Fixed &val1, const Fixed &val2); Fixed operator - (const Fixed &val1, const Fixed &val2); Fixed operator * (const Fixed &val1, const Fixed &val2); Fixed operator / (const Fixed &val1, const Fixed &val2); Fixed operator > (const Fixed &val1, const FIxed &val2); Fixed operator < (const Fixed &val1, const FIxed &val2); Fixed operator >= (const Fixed &val1, const FIxed &val2); Fixed operator <= (const Fixed &val1, const FIxed &val2); Fixed operator == (const Fixed &val1, const FIxed &val2); Fixed operator != (const Fixed &val1, const FIxed &val2); -------------------------------------------------------------------------------- 20.16.2 -------------------------------------------------------------------------------- 20.16.3 -------------------------------------------------------------------------------- 20.39.4 -------------------------------------------------------------------------------- -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Mon, 20 Jul 1998 14:22:39 -0700 From: Jonathan Biggar To: cxx_revision@omg.org Subject: Proposal to "fix" fixed point in the C++ mapping :-) [Ok, here is the real version of the proposal. Jump in and comment as quickly as you can so that we can get this into a C++ RTF report in time for CORBA 2.3. You don't need to be gentle--I don't bite.] This proposal addresses the following issues: Issue 1056: Fixed types in orbos/98-01-11 Issue 1069: Typos on p 20-34 of orbos/98-01-11 Issue 1070: macros for fixed arithmetic results Issue 1072: fixed_digits and fixed_scale member functions Issue 1073: Missing constructor for Fixed Issue 1092: C++ mapping for fixed is broken (01) Issue 1093: C++ mapping for fixed is broken (02) Issue 1124: C++ Fixed type issue (01) Issue 1125: Fixed type (02) Issue 1126: C++ Fixed Type (03) Issue 1538: Missing text describing fixed point constant mapping Summary description of the problems with fixed: The worst problem with the existing CORBA 2.2 mapping for fixed point types is the attempted use of a template type with the digits and scale as template arguments. This causes two major problems, neither of which is possible to fix without reworking the mapping entirely. The first is that the Fixed is defined as a template in the CORBA namespace. This cannot be implemented in a compiler that does not support either namespaces or member templates. Since there are still quite a few compilers with this deficiency, this is a bad idea for a fundamental type. The second problem is that the arithmetic for fixed point types (particularly the divide operation) defines the digits and scale of the result of binary mathematics operations (+, -, *, /) to depend on the runtime values of the arguments. This cannot be expressed using C++ template declarations, since the digits and scale must be compile time constants. The second problem area with the fixed point mapping is that the mapping totally ignores fixed point constant declarations and how to map them into C++. For an IDL fixed point declaration: const fixed foo = 1.2D; neither the use of the keyword "fixed" without digits and scale parameters, nor the actual fixed point literal, "1.2D" have a mapping into C++. The third major problem area has to do with the IDL grammar itself. The CORBA 2.2 grammar allows fixed point types to be defined anonymously (without a typedef) as IDL operation parameters or return types. But since the C++ mapping specifies that _var and _out types are defined for anonymous fixed point types, this causes two problems: first, the mapping does not define how to handle a negative scale when determining the name for the _var and _out types for an anonymous fixed point type, and second, there is no clear place to define the _var and _out types when an anonymous fixed point type is used as an IDL parameter or return type. Overview of the Proposal: The key to the proposal is to redefine CORBA::Fixed to be a non-template type that can handle any combination of digits and scale at run time. All of the arithmetic operations are defined using CORBA::Fixed. However, this proposal does not require that CORBA::Fixed be used as the type for operation parameters and fields in IDL structured types (struct, union, sequence, array, etc). The reason for this is that a generic fixed point value needs about 18 bytes of storage, minimum--16 for the 31 digits plus sign, 2 for the digits and scale values. So, by allowing the implementation to choose to use another type for fixed point types with an explicit digits and scale, this gives the implementation the flexibility to reduce the storage cost for fixed point types in places where the digits and scale are known. It also allows the implementation to code the bounds check for digits and scale into the conversion between the "generic" CORBA::Fixed type and the actual type used for operation parameters and structured members, rather than having to add code at runtime to check these bounds inside the marshaling engine. In fact, an implementation could still use a template for these unnamed types without the problems described above, since the implementation is free to declare the template however it needs to. The second problem, that the mapping for fixed point constants is not specified, is solved by mapping fixed point constants to normal C++ string literals. The third problem, issues with declaring _out & _var types for fixed point has been mainly resolved by the ORB core RTF, which has already approved a fix that obviate the need for the C++ RTF to fix these problems. The proposal accepted by the core RTF are to forbid the declaration of anonymous fixed types as IDL operation parameters. In addition, the proposal presented here eliminates the _var type for fixed point types, because it is unnecessary. This proposal just treats C++ fixed point types like built-in C++ types. Since a maximal sized fixed point type needs little if any more storage than a long double, which is passed by value, there isn't much need to use dynamic storage (new and delete) for fixed point values. Besides, the C++ mapping specifies that fixed point types are always passed by reference, and never by pointer. The ORB core RTF has also passed a proposal that outlaws the use of a negative scale, since the original CORBA 2.2 specification stated that this was not portable anyway. Proposal: Make the following changes to the CORBA 2.2 C++ mapping (section 20): -------------------------------------------------------------------------------- Add the following paragraphs to the end of section 20.4: Fixed Point Constants Since C++ does not have a native fixed point type, IDL fixed point literals are mapped to C++ strings without the trailing 'd' or 'D' in order to guarantee that there is no loss of precision. For example, the IDL fixed point literal 123.456D is mapped to the C++ string "123.456". -------------------------------------------------------------------------------- Replace the entire text of section 20.11 with: 20.11 Mapping for Fixed The C++ mapping for fixed is defined by the following class: class Fixed { public: // Constructors... Fixed(int val = 0); Fixed(unsigned val); Fixed(Long val); Fixed(ULong val); Fixed(LongLong val); Fixed(ULongLong val); Fixed(Double val); Fixed(LongDouble val); Fixed(const Fixed& val); Fixed(const char *); ~Fixed(); // Conversions... operator LongLong() const; operator LongDouble() const; Fixed round(UShort digits, UShort scale) const; Fixed truncate(UShort digits, UShort scale) const; char *to_string(); // Operators... Fixed& operator=(const Fixed& val); Fixed& operator+=(const Fixed& val); Fixed& operator-=(const Fixed& val); Fixed& operator*=(const Fixed& val); Fixed& operator/=(const Fixed& val); Fixed& operator++(); Fixed& operator++(int); Fixed& operator--(); Fixed& operator--(int); Fixed& operator+() const; Fixed& operator-() const; int operator!() const; // Other member functions UShort fixed_digits() const; UShort fixed_scale() const; }; istream& operator>>(istream& is, Fixed &val); ostream& operator<<(ostream& os, const Fixed &val); Fixed operator + (const Fixed &val1, const Fixed &val2); Fixed operator - (const Fixed &val1, const Fixed &val2); Fixed operator * (const Fixed &val1, const Fixed &val2); Fixed operator / (const Fixed &val1, const Fixed &val2); Fixed operator > (const Fixed &val1, const Fixed &val2); Fixed operator < (const Fixed &val1, const Fixed &val2); Fixed operator >= (const Fixed &val1, const Fixed &val2); Fixed operator <= (const Fixed &val1, const Fixed &val2); Fixed operator == (const Fixed &val1, const Fixed &val2); Fixed operator != (const Fixed &val1, const Fixed &val2); The Fixed class is used directly by the C++ mapping for IDL fixed point constant values and for all intermediate results of arithmetic operations on fixed point values. For fixed point parameters of IDL operations or members of IDL structured datatypes, the implementation may use the Fixed type directly, or alternatively, may use a different type, with an effectively constant digits and scale, that provides the same C++ interface and can be implicitly converted from/to the Fixed class. The name(s) of this alternative class is not defined by this mapping. Since fixed point types used as parameters of IDL operations must be named via an IDL typedef declaration, the mapping must use the typedef to define the type of the operation parameter to make sure that server side operation signatures are portable. The Fixed class has a number of constructors to guarantee that a fixed value can be constructed from any of the IDL standard integer and floating point types. The Fixed(char *) constructor converts a string representation of a fixed point literal into a real fixed point value, with the trailing 'd' or 'D' optional. The Fixed class also provides conversion operators back to the LongLong and LongDouble types. The to_string() function provides an explicit conversion of a fixed point value to a string representation without the trailing 'd' or 'D'. The returned string value must be released by the caller using CORBA::string_free(). The round() and truncate() functions convert a fixed value to a new value with the specified digits and scale. If the new digits and scale require the value to loose precision on the right, the round() function will round away from zero values that are halfway or more to the next absolute value for the new fixed precision. The truncate() function always truncates the value towards zero. So, for example: Fixed f1 = "0.1"; Fixed f2 = "0.05"; Fixed f3 = "-0.005; f1.round(1,0) and f1.truncate(1,0) both return 0., f2.round(2,1) returns 0.1, f2.truncate(2,1) returns 0.0, f3.round(3,2) returns -0.01 and f3.truncate returns 0.00. The fixed_digits() and fixed_scale() functions return the smallest digits and scale value that can hold the complete fixed point value. If the implementation uses alternative classes for operation parameters and structured type members, then fixed_digits() and fixed_scale() return the constant digits and scale values defined by the source IDL fixed point type. Arithmetic operations on the Fixed class must calculate the result exactly, using an effective double precision (62 digit) temporary value. The results are then truncated at run time to fit in a maximum of 31 digits using the method defined in 3.7.2 to determine the new digits and scale. If the result of any arithmetic operation produces more than 31 digits to the left of the decimal point, the DATA_CONVERSION exception will be thrown. If a fixed point value, used as an actual operation parameter or assigned to a member of an IDL structured datatype, exceeds the maximum absolute value implied by the digits and scale, the DATA_CONVERSION exception will be thrown. The stream insertion and extraction operators << and >> convert a fixed point value to/from a stream using the format defined for an IDL fixed point literal. For stream insertion, the trailing 'd' or 'D' is left off, and for stream insertion, the 'd' or 'D' is optional. 20.11.1 Fixed T_var and T_out Types Since fixed point types are always passed by reference as operation parameters and returned by value, there is no need for a _var type for fixed point. For each IDL fixed point typedef a corresponding _out type is defined as a reference to the fixed point type: // IDL typedef fixed<5,2> F; // C++ typedef Implementation_Defined_name F; typedef F &F_out; -------------------------------------------------------------------------------- In section 20.16.2, add the following bullet to the first bullet list: o Fixed types and change the following paragraph to: For values of type T that are too large to be passed by value efficiently, such as structs, unions, sequences, Any, and exceptions, two forms of the insertion function are provided. -------------------------------------------------------------------------------- In section 20.16.3, add the following bullet to the first bullet list: o Fixed types and change the paragraph that reads: "For non-primitive types, such as struct, union, sequence, exception, Any, and fixed types, extraction is done by pointer. For example, consider the following IDL struct:" to: For non-primitive types, such as struct, union, sequence, exception, and Any, extraction is done by pointer. For example, consider the following IDL struct: -------------------------------------------------------------------------------- In section 20.39.4 add the following member functions to the Any class right after the corresponding Double operations: void operator<<=(const Fixed &); void operator>>=(Fixed &); -------------------------------------------------------------------------------- Change the fixed point type row in Table 20-2 to: fixed const Fixed & Fixed & Fixed & Fixed -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Tue, 21 Jul 1998 08:07:14 -0700 From: Jonathan Biggar To: cxx_revision@omg.org Subject: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) [Here is version 2 of the proposal. I realized last night that inserting and extracting fixed point to/from an any required from_fixed & to_fixed classes to specify the digits and scale that should be embedded in the TypeCode. So the parts dealing with any have been rewritten.] This proposal addresses the following issues: Issue 1056: Fixed types in orbos/98-01-11 Issue 1069: Typos on p 20-34 of orbos/98-01-11 Issue 1070: macros for fixed arithmetic results Issue 1072: fixed_digits and fixed_scale member functions Issue 1073: Missing constructor for Fixed Issue 1092: C++ mapping for fixed is broken (01) Issue 1093: C++ mapping for fixed is broken (02) Issue 1124: C++ Fixed type issue (01) Issue 1125: Fixed type (02) Issue 1126: C++ Fixed Type (03) Issue 1538: Missing text describing fixed point constant mapping Summary description of the problems with fixed: The worst problem with the existing CORBA 2.2 mapping for fixed point types is the attempted use of a template type with the digits and scale as template arguments. This causes two major problems, neither of which is possible to fix without reworking the mapping entirely. The first is that the Fixed is defined as a template in the CORBA namespace. This cannot be implemented in a compiler that does not support either namespaces or member templates. Since there are still quite a few compilers with this deficiency, this is a bad idea for a fundamental type. The second problem is that the arithmetic for fixed point types (particularly the divide operation) defines the digits and scale of the result of binary mathematics operations (+, -, *, /) to depend on the runtime values of the arguments. This cannot be expressed using C++ template declarations, since the digits and scale must be compile time constants. The second problem area with the fixed point mapping is that the mapping totally ignores fixed point constant declarations and how to map them into C++. For an IDL fixed point declaration: const fixed foo = 1.2D; neither the use of the keyword "fixed" without digits and scale parameters, nor the actual fixed point literal, "1.2D" have a mapping into C++. The third major problem area has to do with the IDL grammar itself. The CORBA 2.2 grammar allows fixed point types to be defined anonymously (without a typedef) as IDL operation parameters or return types. But since the C++ mapping specifies that _var and _out types are defined for anonymous fixed point types, this causes two problems: first, the mapping does not define how to handle a negative scale when determining the name for the _var and _out types for an anonymous fixed point type, and second, there is no clear place to define the _var and _out types when an anonymous fixed point type is used as an IDL parameter or return type. Overview of the Proposal: The key to the proposal is to redefine CORBA::Fixed to be a non-template type that can handle any combination of digits and scale at run time. All of the arithmetic operations are defined using CORBA::Fixed. However, this proposal does not require that CORBA::Fixed be used as the type for operation parameters and fields in IDL structured types (struct, union, sequence, array, etc). The reason for this is that a generic fixed point value needs about 18 bytes of storage, minimum--16 for the 31 digits plus sign, 2 for the digits and scale values. So, by allowing the implementation to choose to use another type for fixed point types with an explicit digits and scale, this gives the implementation the flexibility to reduce the storage cost for fixed point types in places where the digits and scale are known. It also allows the implementation to code the bounds check for digits and scale into the conversion between the "generic" CORBA::Fixed type and the actual type used for operation parameters and structured members, rather than having to add code at runtime to check these bounds inside the marshaling engine. In fact, an implementation could still use a template for these unnamed types without the problems described above, since the implementation is free to declare the template however it needs to. The second problem, that the mapping for fixed point constants is not specified, is solved by mapping fixed point constants to normal C++ string literals. The third problem, issues with declaring _out & _var types for fixed point has been mainly resolved by the ORB core RTF, which has already approved a fix that obviate the need for the C++ RTF to fix these problems. The proposal accepted by the core RTF are to forbid the declaration of anonymous fixed types as IDL operation parameters. In addition, the proposal presented here eliminates the _var type for fixed point types, because it is unnecessary. This proposal just treats C++ fixed point types like built-in C++ types. Since a maximal sized fixed point type needs little if any more storage than a long double, which is passed by value, there isn't much need to use dynamic storage (new and delete) for fixed point values. Besides, the C++ mapping specifies that fixed point types are always passed by reference, and never by pointer. The ORB core RTF has also passed a proposal that outlaws the use of a negative scale, since the original CORBA 2.2 specification stated that this was not portable anyway. Proposal: Make the following changes to the CORBA 2.2 C++ mapping (section 20): -------------------------------------------------------------------------------- Add the following paragraphs to the end of section 20.4: Fixed Point Constants Since C++ does not have a native fixed point type, IDL fixed point literals are mapped to C++ strings without the trailing 'd' or 'D' in order to guarantee that there is no loss of precision. For example, the IDL fixed point literal 123.456D is mapped to the C++ string "123.456". -------------------------------------------------------------------------------- Replace the entire text of section 20.11 with: 20.11 Mapping for Fixed The C++ mapping for fixed is defined by the following class: class Fixed { public: // Constructors... Fixed(int val = 0); Fixed(unsigned val); Fixed(Long val); Fixed(ULong val); Fixed(LongLong val); Fixed(ULongLong val); Fixed(Double val); Fixed(LongDouble val); Fixed(const Fixed& val); Fixed(const char *); ~Fixed(); // Conversions... operator LongLong() const; operator LongDouble() const; Fixed round(UShort digits, UShort scale) const; Fixed truncate(UShort digits, UShort scale) const; char *to_string(); // Operators... Fixed& operator=(const Fixed& val); Fixed& operator+=(const Fixed& val); Fixed& operator-=(const Fixed& val); Fixed& operator*=(const Fixed& val); Fixed& operator/=(const Fixed& val); Fixed& operator++(); Fixed& operator++(int); Fixed& operator--(); Fixed& operator--(int); Fixed& operator+() const; Fixed& operator-() const; int operator!() const; // Other member functions UShort fixed_digits() const; UShort fixed_scale() const; }; istream& operator>>(istream& is, Fixed &val); ostream& operator<<(ostream& os, const Fixed &val); Fixed operator + (const Fixed &val1, const Fixed &val2); Fixed operator - (const Fixed &val1, const Fixed &val2); Fixed operator * (const Fixed &val1, const Fixed &val2); Fixed operator / (const Fixed &val1, const Fixed &val2); Fixed operator > (const Fixed &val1, const Fixed &val2); Fixed operator < (const Fixed &val1, const Fixed &val2); Fixed operator >= (const Fixed &val1, const Fixed &val2); Fixed operator <= (const Fixed &val1, const Fixed &val2); Fixed operator == (const Fixed &val1, const Fixed &val2); Fixed operator != (const Fixed &val1, const Fixed &val2); The Fixed class is used directly by the C++ mapping for IDL fixed point constant values and for all intermediate results of arithmetic operations on fixed point values. For fixed point parameters of IDL operations or members of IDL structured datatypes, the implementation may use the Fixed type directly, or alternatively, may use a different type, with an effectively constant digits and scale, that provides the same C++ interface and can be implicitly converted from/to the Fixed class. The name(s) of this alternative class is not defined by this mapping. Since fixed point types used as parameters of IDL operations must be named via an IDL typedef declaration, the mapping must use the typedef to define the type of the operation parameter to make sure that server side operation signatures are portable. The Fixed class has a number of constructors to guarantee that a fixed value can be constructed from any of the IDL standard integer and floating point types. The Fixed(char *) constructor converts a string representation of a fixed point literal into a real fixed point value, with the trailing 'd' or 'D' optional. The Fixed class also provides conversion operators back to the LongLong and LongDouble types. The to_string() function provides an explicit conversion of a fixed point value to a string representation without the trailing 'd' or 'D'. The returned string value must be released by the caller using CORBA::string_free(). The round() and truncate() functions convert a fixed value to a new value with the specified digits and scale. If the new digits and scale require the value to loose precision on the right, the round() function will round away from zero values that are halfway or more to the next absolute value for the new fixed precision. The truncate() function always truncates the value towards zero. So, for example: Fixed f1 = "0.1"; Fixed f2 = "0.05"; Fixed f3 = "-0.005; f1.round(1,0) and f1.truncate(1,0) both return 0., f2.round(2,1) returns 0.1, f2.truncate(2,1) returns 0.0, f3.round(3,2) returns -0.01 and f3.truncate returns 0.00. The fixed_digits() and fixed_scale() functions return the smallest digits and scale value that can hold the complete fixed point value. If the implementation uses alternative classes for operation parameters and structured type members, then fixed_digits() and fixed_scale() return the constant digits and scale values defined by the source IDL fixed point type. Arithmetic operations on the Fixed class must calculate the result exactly, using an effective double precision (62 digit) temporary value. The results are then truncated at run time to fit in a maximum of 31 digits using the method defined in 3.7.2 to determine the new digits and scale. If the result of any arithmetic operation produces more than 31 digits to the left of the decimal point, the DATA_CONVERSION exception will be thrown. If a fixed point value, used as an actual operation parameter or assigned to a member of an IDL structured datatype, exceeds the maximum absolute value implied by the digits and scale, the DATA_CONVERSION exception will be thrown. The stream insertion and extraction operators << and >> convert a fixed point value to/from a stream using the format defined for an IDL fixed point literal. For stream insertion, the trailing 'd' or 'D' is left off, and for stream insertion, the 'd' or 'D' is optional. 20.11.1 Fixed T_var and T_out Types Since fixed point types are always passed by reference as operation parameters and returned by value, there is no need for a _var type for fixed point. For each IDL fixed point typedef a corresponding _out type is defined as a reference to the fixed point type: // IDL typedef fixed<5,2> F; // C++ typedef Implementation_Defined_name F; typedef F &F_out; -------------------------------------------------------------------------------- In section 20.16.2, change the paragraph that reads: For values of type T that are too large to be passed by value efficiently, such as structs, unions, sequences, fixed types, Any, and exceptions, two forms of the insertion function are provided. to: For values of type T that are too large to be passed by value efficiently, such as structs, unions, sequences, Any, and exceptions, two forms of the insertion function are provided. -------------------------------------------------------------------------------- In section 20.16.3, change the paragraph that reads: "For non-primitive types, such as struct, union, sequence, exception, Any, and fixed types, extraction is done by pointer. For example, consider the following IDL struct:" to: For non-primitive types, such as struct, union, sequence, exception, and Any, extraction is done by pointer. For example, consider the following IDL struct: -------------------------------------------------------------------------------- Changed the title of section 20.16.4 to: 20.16.4 Distinguishing boolean, octet, char, wchar, bounded string, bounded wstring and fixed Change the first paragraph to: Since the boolean, octet, char, and wchar OMG IDL types are not required to map to distinct C++ types, another means of distinguishing them from each other is necessary so that they can be used with the type-safe any interface. Similarly, since both bounded and unbounded strings map to char*, both bounded and unbounded wide strings map to WChar*, and all fixed point types map to FixeD, another means of distinguishing them must be provided. This is done by introducing several new helper types nested in the any class interface. Add the following declaration to the Any class right after the corresponding from_wstring/to_wstring references: struct from_fixed { from_fixed(const Fixed &f, UShort d, UShort s) : val(f), digits(d), scale(s) { } const Fixed &val; UShort digits; UShort scale; }; void operator <<=(from_fixed); struct to_fixed { to_fixed(Fixed &f, UShort d, UShort s); Fixed &val; UShort digits; UShort scale; }; void operator >>=(to_fixed) const; Also add these declarations to the Any class in section 20.39.4. Add the following to the end of the example on page 20.54: Fixed f = "123.45"; any <<= Any::from_fixed(f, 5, 2); // ... if (any >>= Any::to_fixed(f, 5, 2)) { v // ...any contains a fixed<5,2> } -------------------------------------------------------------------------------- Change the fixed point type row in Table 20-2 to: fixed const Fixed & Fixed & Fixed & Fixed -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Tue, 21 Jul 1998 17:05:35 -0700 From: Jonathan Biggar To: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <35B4AEA2.B361FE28@floorboard.com> Jonathan Biggar wrote: > > [Here is version 2 of the proposal. I realized last night that > inserting and extracting fixed point to/from an any required > from_fixed > & to_fixed classes to specify the digits and scale that should be > embedded in the TypeCode. So the parts dealing with any have been > rewritten.] Ok guys, you now had a day or so to look this proposal over. If we are to have any chance to get this into CORBA 2.3, I need feedback quickly! -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Sender: vinoski@mail.boston.iona.ie Date: Tue, 21 Jul 1998 22:53:10 -0400 To: Jonathan Biggar From: Steve Vinoski Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) Cc: cxx_revision@omg.org References: <35B4AEA2.B361FE28@floorboard.com> At 05:05 PM 7/21/98 -0700, Jonathan Biggar wrote: >Jonathan Biggar wrote: >> >> [Here is version 2 of the proposal. I realized last night that >> inserting and extracting fixed point to/from an any required from_fixed >> & to_fixed classes to specify the digits and scale that should be >> embedded in the TypeCode. So the parts dealing with any have been >> rewritten.] > >Ok guys, you now had a day or so to look this proposal over. If we are >to have any chance to get this into CORBA 2.3, I need feedback quickly! Jon, our initial reaction is that it looks pretty good. I will try to look it over in detail tomorrow and will send any comments I might have at that vtime. --steve Return-Path: Sender: jon@floorboard.com Date: Tue, 21 Jul 1998 21:22:01 -0700 From: Jonathan Biggar To: Steve Vinoski CC: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <35B4AEA2.B361FE28@floorboard.com> <199807220254.WAA10704@boston.iona.ie> Steve Vinoski wrote: > > At 05:05 PM 7/21/98 -0700, Jonathan Biggar wrote: > >Jonathan Biggar wrote: > >> > >> [Here is version 2 of the proposal. I realized last night that > >> inserting and extracting fixed point to/from an any required > from_fixed > >> & to_fixed classes to specify the digits and scale that should be > >> embedded in the TypeCode. So the parts dealing with any have > been > >> rewritten.] > > > >Ok guys, you now had a day or so to look this proposal over. If we > are > >to have any chance to get this into CORBA 2.3, I need feedback > quickly! > > Jon, our initial reaction is that it looks pretty good. I will try > to look > it over in detail tomorrow and will send any comments I might have > at that > time. Just to let you all know, I test compiled the Fixed class from my proposal using the sun 4.2 CC compiler and everything passed with flying colors. One thing I just thought of is that I might have add some text to the istream and ostream operator part to make it clear that the declarations of these operators should be adjusted to handle the ANSIness or lack thereof of the C++ environment. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Sender: vinoski@mail.boston.iona.ie Date: Thu, 23 Jul 1998 19:05:21 -0400 To: Jonathan Biggar From: Steve Vinoski Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) Cc: cxx_revision@omg.org At 08:07 AM 7/21/98 -0700, Jonathan Biggar wrote: >istream& operator>>(istream& is, Fixed &val); Jon, is there a need to define the formats that are acceptable to operator>>? Seems like there is, otherwise programs won't be able to portably read fixed-point input. --steve Return-Path: Sender: jon@floorboard.com Date: Thu, 23 Jul 1998 18:28:33 -0700 From: Jonathan Biggar To: Steve Vinoski CC: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <199807232306.TAA03687@boston.iona.ie> Steve Vinoski wrote: > > At 08:07 AM 7/21/98 -0700, Jonathan Biggar wrote: > >istream& operator>>(istream& is, Fixed &val); > > Jon, is there a need to define the formats that are acceptable to > operator>>? Seems like there is, otherwise programs won't be able to > portably read fixed-point input. Is there something about this sentence (which was in my version 2 proposal) that is insufficent? [Other than that I just changed it because I accidentally typed "insertion" when I meant "extraction"? :-)] The stream insertion and extraction operators << and >> convert a fixed point value to/from a stream using the format defined for an IDL fixed point literal. For stream insertion, the minimal number of digits that fully represents the value will be inserted, along with a decimal point, while the trailing 'd' or 'D' is left off. For stream extraction, the 'd' or 'D' is optional. [ Ok, I confess, I just edited the sentence again to tighten up the definition of stream insertion. The key here is that it states that the format the same as what is defined for an IDL literal.] -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Sender: vinoski@mail.boston.iona.ie Date: Thu, 23 Jul 1998 22:25:51 -0400 To: Jonathan Biggar From: Steve Vinoski Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) Cc: cxx_revision@omg.org References: <199807232306.TAA03687@boston.iona.ie> At 06:28 PM 7/23/98 -0700, Jonathan Biggar wrote: >Is there something about this sentence (which was in my version 2 >proposal) that is insufficent? [Other than that I just changed it >because I accidentally typed "insertion" when I meant "extraction"? :-)] > >The stream insertion and extraction operators << and >> convert a fixed >point value to/from a stream using the format defined for an IDL fixed >point literal. For stream insertion, the minimal number of digits that >fully represents the value will be inserted, along with a decimal point, >while the trailing 'd' or 'D' is left off. For stream extraction, the >'d' or 'D' is optional. > >[ Ok, I confess, I just edited the sentence again to tighten up the >definition of stream insertion. The key here is that it states that the >format the same as what is defined for an IDL literal.] Oops, sorry, we had saved this question from the first proposal and I forgot to check if it had been addressed in the second one. With that resolved, IONA votes yes to adopt your new C++ mapping for fixed. --steve Return-Path: Sender: jon@floorboard.com Date: Thu, 23 Jul 1998 19:36:19 -0700 From: Jonathan Biggar To: Steve Vinoski CC: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <199807232306.TAA03687@boston.iona.ie> <199807240227.WAA07023@boston.iona.ie> Steve Vinoski wrote: > > At 06:28 PM 7/23/98 -0700, Jonathan Biggar wrote: > >Is there something about this sentence (which was in my version 2 > >proposal) that is insufficent? [Other than that I just changed it > >because I accidentally typed "insertion" when I meant "extraction"? > :-)] > > > >The stream insertion and extraction operators << and >> convert a > fixed > >point value to/from a stream using the format defined for an IDL > fixed > >point literal. For stream insertion, the minimal number of digits > that > >fully represents the value will be inserted, along with a decimal > point, > >while the trailing 'd' or 'D' is left off. For stream extraction, > the > >'d' or 'D' is optional. > > > >[ Ok, I confess, I just edited the sentence again to tighten up the > >definition of stream insertion. The key here is that it states > that the > >format the same as what is defined for an IDL literal.] > > Oops, sorry, we had saved this question from the first proposal and > I > forgot to check if it had been addressed in the second one. > > With that resolved, IONA votes yes to adopt your new C++ mapping for > fixed. Well, that's two. :-) Anyone else want to jump in and vote on this one and/or the refcount proposal? This is your chance to make history! -- 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: Fri, 24 Jul 1998 13:20:15 +1000 (EST) From: Michi Henning Reply-To: Michi Henning To: Jonathan Biggar cc: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) On Tue, 21 Jul 1998, Jonathan Biggar wrote: > The proposal accepted by the core RTF are to forbid the > declaration of anonymous fixed types as IDL operation parameters. Jon, I am not quite sure what the final resolution was for anonymous types. I would suggest to completely outlaw them and to require a typedef *always*. Someone just raised yet another issue on anonymous types, and I think here is our chance to get rid of them once and for all, at least for fixed types. > Add the following paragraphs to the end of section 20.4: > > Fixed Point Constants > > Since C++ does not have a native fixed point type, IDL fixed point > literals are mapped to C++ strings without the trailing 'd' or 'D' > in > order to guarantee that there is no loss of precision. For example, > the > IDL fixed point literal 123.456D is mapped to the C++ string > "123.456". I think we may need some extra words here. Otherwise I might get the wrong impression. From the above, I could possibly conclude that // IDL const fixed foo = 1.1D; maps to // C++ const char * foo = "1.1"; I'd insert an example for the mapping for fixed-point IDL constants in the section about the constant mapping. > class Fixed { > public: > // Constructors... > Fixed(int val = 0); > Fixed(unsigned val); > Fixed(Long val); > Fixed(ULong val); > Fixed(LongLong val); > Fixed(ULongLong val); > Fixed(Double val); > Fixed(LongDouble val); > Fixed(const Fixed& val); > Fixed(const char *); > ~Fixed(); > > // Conversions... > operator LongLong() const; > operator LongDouble() const; > Fixed round(UShort digits, UShort scale) const; > Fixed truncate(UShort digits, UShort scale) const; > char *to_string(); Jon, should we add conversions such that they become symmetrical with the constructors? If I can construct a Fixed from a Long, then I don't see why I shouldn't be able to convert to a long? Also, I don't think the text mentions what the behavior should be of converting a Fixed to a LongLong -- does it truncate or round? We should state the behavior. > > // Operators... > Fixed& operator=(const Fixed& val); > Fixed& operator+=(const Fixed& val); > Fixed& operator-=(const Fixed& val); > Fixed& operator*=(const Fixed& val); > Fixed& operator/=(const Fixed& val); > > Fixed& operator++(); > Fixed& operator++(int); > Fixed& operator--(); > Fixed& operator--(int); > Fixed& operator+() const; > Fixed& operator-() const; > int operator!() const; Is it really necessary to have a ! operator? It seems silly to want to use a Fixed value as a boolean? Also, if there is a conversion to LongLong, doesn't that mean no ! operator is necessary? > istream& operator>>(istream& is, Fixed &val); > ostream& operator<<(ostream& os, const Fixed &val); Do we need ostream manipulators for Fixed point values so I can control the number of digits that are printed before and after the decimal point? I can do this with floating point values, so I think I should be able to do it for Fixed point values. Only one glitch -- off-hand, I am not sure whether it is possible to extend iostreams with manipulators for new types without major pain. Anybody know? > Fixed operator + (const Fixed &val1, const Fixed &val2); > Fixed operator - (const Fixed &val1, const Fixed &val2); > Fixed operator * (const Fixed &val1, const Fixed &val2); > Fixed operator / (const Fixed &val1, const Fixed &val2); >From these definitions and the conversion operators, it appears that mixed-mode fixed-point arithmetic is possible only for LongLong and LongDouble. Do we need to support mixed-mode arithmetic for other types (i.e. int, long, short, float, double) as well? > Fixed operator > (const Fixed &val1, const Fixed &val2); > Fixed operator < (const Fixed &val1, const Fixed &val2); > Fixed operator >= (const Fixed &val1, const Fixed &val2); > Fixed operator <= (const Fixed &val1, const Fixed &val2); > Fixed operator == (const Fixed &val1, const Fixed &val2); > Fixed operator != (const Fixed &val1, const Fixed &val2); Same here. Looks like mixed mode comparison won't work? I think we would need appropriate conversions from other types to fixed to make things like the following possible: Fixed f = "1.11"; if (f < 10) // ... > The Fixed class is used directly by the C++ mapping for IDL fixed point > constant values and for all intermediate results of arithmetic > operations on fixed point values. What is the result type of a mixed-mode computation? Always Fixed? If so, I think we need to state this. > For fixed point parameters of IDL > operations or members of IDL structured datatypes, the > implementation > may use the Fixed type directly, or alternatively, may use a > different > type, with an effectively constant digits and scale, that provides > the > same C++ interface and can be implicitly converted from/to the Fixed > class. The name(s) of this alternative class is not defined by this > mapping. Since fixed point types used as parameters of IDL > operations > must be named via an IDL typedef declaration, the mapping must use > the > typedef to define the type of the operation parameter to make sure > that > server side operation signatures are portable. The last sentence is confusing to me -- I'm not sure exactly what you mean here. I think an example would help enormously here. > The Fixed class also provides > conversion operators back to the LongLong and LongDouble types. Need to state whether the conversion operators round or truncate. 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: Thu, 23 Jul 1998 20:45:18 -0700 From: Jonathan Biggar To: Michi Henning CC: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: Michi Henning wrote: > > On Tue, 21 Jul 1998, Jonathan Biggar wrote: > > > The proposal accepted by the core RTF are to forbid the > > declaration of anonymous fixed types as IDL operation parameters. > > Jon, I am not quite sure what the final resolution was for anonymous > types. > I would suggest to completely outlaw them and to require a typedef > *always*. > Someone just raised yet another issue on anonymous types, and I > think > here is our chance to get rid of them once and for all, at least for > fixed types. The final resolution was to remove anonymous fixed from parameter declarations so that fixed is symetrical with the other template types (strings & sequences). > > Add the following paragraphs to the end of section 20.4: > > > > Fixed Point Constants > > > > Since C++ does not have a native fixed point type, IDL fixed point > > literals are mapped to C++ strings without the trailing 'd' or 'D' > in > > order to guarantee that there is no loss of precision. For > example, the > > IDL fixed point literal 123.456D is mapped to the C++ string > "123.456". > > I think we may need some extra words here. Otherwise I might get the > wrong impression. From the above, I could possibly conclude that > > // IDL > const fixed foo = 1.1D; > > maps to > // C++ > const char * foo = "1.1"; > > I'd insert an example for the mapping for fixed-point IDL constants > in the > section about the constant mapping. Good idea. > > class Fixed { > > public: > > // Constructors... > > Fixed(int val = 0); > > Fixed(unsigned val); > > Fixed(Long val); > > Fixed(ULong val); > > Fixed(LongLong val); > > Fixed(ULongLong val); > > Fixed(Double val); > > Fixed(LongDouble val); > > Fixed(const Fixed& val); > > Fixed(const char *); > > ~Fixed(); > > > > // Conversions... > > operator LongLong() const; > > operator LongDouble() const; > > Fixed round(UShort digits, UShort scale) const; > > Fixed truncate(UShort digits, UShort scale) const; > > char *to_string(); > > Jon, should we add conversions such that they become symmetrical > with > the constructors? If I can construct a Fixed from a Long, then I > don't > see why I shouldn't be able to convert to a long? Because if I define too many conversion operators then they all become ambiguous unless explicitly qualified. There are more constructors due to my reading of the C++ integral type promotion rules (they appear to only convert automatically up to int or unsigned, for long and larger you need explicit constructors to guarantee things work right.) > Also, I don't think the text mentions what the behavior should be of > converting a Fixed to a LongLong -- does it truncate or round? We > should > state the behavior. I could do that better. There is text further on that states that arithmetic operations that go out of bounds throw DATA_CONVERSION. These should also. > > > > // Operators... > > Fixed& operator=(const Fixed& val); > > Fixed& operator+=(const Fixed& val); > > Fixed& operator-=(const Fixed& val); > > Fixed& operator*=(const Fixed& val); > > Fixed& operator/=(const Fixed& val); > > > > Fixed& operator++(); > > Fixed& operator++(int); > > Fixed& operator--(); > > Fixed& operator--(int); > > Fixed& operator+() const; > > Fixed& operator-() const; > > int operator!() const; > > Is it really necessary to have a ! operator? It seems silly to want > to > use a Fixed value as a boolean? If we don't have it, someone will complain. > Also, if there is a conversion to LongLong, doesn't that mean no ! operator > is necessary? Probably, but the ! operator might be faster. > > istream& operator>>(istream& is, Fixed &val); > > ostream& operator<<(ostream& os, const Fixed &val); > > Do we need ostream manipulators for Fixed point values so I can > control > the number of digits that are printed before and after the decimal > point? > I can do this with floating point values, so I think I should be > able > to do it for Fixed point values. Only one glitch -- off-hand, I am > not > sure whether it is possible to extend iostreams with manipulators > for new > types without major pain. Anybody know? Good question. I don't think I even want to get into the manipulator stuff now. > > Fixed operator + (const Fixed &val1, const Fixed &val2); > > Fixed operator - (const Fixed &val1, const Fixed &val2); > > Fixed operator * (const Fixed &val1, const Fixed &val2); > > Fixed operator / (const Fixed &val1, const Fixed &val2); > > >From these definitions and the conversion operators, it appears > that > mixed-mode fixed-point arithmetic is possible only for LongLong and > LongDouble. > Do we need to support mixed-mode arithmetic for other types > (i.e. int, long, > short, float, double) as well? Again, the class needs to be careful to avoid unnecessary ambiguity. As it stands right now, adding a fixed and a longlong is ambiguous, because either can be converted to the other. Perhaps I should remove the implicit conversion operators and make everything explicit. > > Fixed operator > (const Fixed &val1, const Fixed &val2); > > Fixed operator < (const Fixed &val1, const Fixed &val2); > > Fixed operator >= (const Fixed &val1, const Fixed &val2); > > Fixed operator <= (const Fixed &val1, const Fixed &val2); > > Fixed operator == (const Fixed &val1, const Fixed &val2); > > Fixed operator != (const Fixed &val1, const Fixed &val2); > > Same here. Looks like mixed mode comparison won't work? I think we > would > need appropriate conversions from other types to fixed to make > things > like the following possible: > > Fixed f = "1.11"; > if (f < 10) > // ... Here there is no problem, since the compiler will correctly use the Fixed(int) constructor. > > The Fixed class is used directly by the C++ mapping for IDL fixed point > > constant values and for all intermediate results of arithmetic > > operations on fixed point values. > > What is the result type of a mixed-mode computation? Always Fixed? If so, > I think we need to state this. At this point either it is Fixed or ambiguous. > > For fixed point parameters of IDL > > operations or members of IDL structured datatypes, the > implementation > > may use the Fixed type directly, or alternatively, may use a > different > > type, with an effectively constant digits and scale, that provides > the > > same C++ interface and can be implicitly converted from/to the > Fixed > > class. The name(s) of this alternative class is not defined by > this > > mapping. Since fixed point types used as parameters of IDL > operations > > must be named via an IDL typedef declaration, the mapping must use > the > > typedef to define the type of the operation parameter to make sure > that > > server side operation signatures are portable. > > The last sentence is confusing to me -- I'm not sure exactly what > you mean > here. I think an example would help enormously here. Ok: // IDL typedef fixed<5,2> F; interface A { void op(in F arg); }; could map to: // C++ // either typedef Fixed F; // or typedef Some_Implementation_Defined_Fixed_Class F; class A : public virtual CORBA::Object { public: void op(const F &arg); }; The point is that the typedef implicitly defines the digits and scale. If the parameters don't use the right typedef, then we don't have server side signature portability. > > The Fixed class also provides > > conversion operators back to the LongLong and LongDouble types. > > Need to state whether the conversion operators round or truncate. Addressed above. -- 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: Fri, 24 Jul 1998 14:02:36 +1000 (EST) From: Michi Henning Reply-To: Michi Henning To: Jonathan Biggar cc: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) On Thu, 23 Jul 1998, Jonathan Biggar wrote: > The final resolution was to remove anonymous fixed from parameter > declarations so that fixed is symetrical with the other template > types > (strings & sequences). Nasty. So we can still write union foo switch(long) { case 0: fixed<3,1> f; case 1: fixed<6,2> g; case 2: sequence foo_seq; case 3: sequence > foo_seq_seq; }; Would have been far better to get rid of anonymous IDL types once and for all... As someone pointed out recently, the C++ mapping still cannot deal with the final case (as rare as it may be). But not to worry, I'll raise an issue and we'll get it next time... ;-) > > Jon, should we add conversions such that they become symmetrical with > > the constructors? If I can construct a Fixed from a Long, then I don't > > see why I shouldn't be able to convert to a long? > > Because if I define too many conversion operators then they all become > ambiguous unless explicitly qualified. There are more constructors due > to my reading of the C++ integral type promotion rules (they appear to > only convert automatically up to int or unsigned, for long and larger > you need explicit constructors to guarantee things work right.) I've forgotten the exact rules for argument matching for constructors (which aren't the same as for function arguments...) I would suggest to use the C++ complex type as a model -- doing the same thing for fixed would probably be the safe and correct way to go. > > Also, I don't think the text mentions what the behavior should be of > > converting a Fixed to a LongLong -- does it truncate or round? We should > > state the behavior. > > I could do that better. There is text further on that states that > arithmetic operations that go out of bounds throw DATA_CONVERSION. > These should also. Yep. But what happens if I convert a fixed<3,2> with value 1.5 to LongLong? DATA_CONVERSION, rounding, or truncation? > > Is it really necessary to have a ! operator? It seems silly to want to > > use a Fixed value as a boolean? > > If we don't have it, someone will complain. TOUGH! Let them complain. After all, we don't have intialization from boolean either, or initialization or conversion to and from char. > > Also, if there is a conversion to LongLong, doesn't that mean no ! operator > > is necessary? > > Probably, but the ! operator might be faster. Tough again... I think I would prefer not to have boolean operators and/or conversions. I don't feel too strongly about this. Again, can we do whatever the C++ complex type does? It seems fair to use that as a model as much as possible. At least then, we can claim that things are consistent. > > > istream& operator>>(istream& is, Fixed &val); > > > ostream& operator<<(ostream& os, const Fixed &val); > > > > Do we need ostream manipulators for Fixed point values so I can > control > > the number of digits that are printed before and after the decimal > point? > > I can do this with floating point values, so I think I should be > able > > to do it for Fixed point values. Only one glitch -- off-hand, I am > not > > sure whether it is possible to extend iostreams with manipulators > for new > > types without major pain. Anybody know? > > Good question. I don't think I even want to get into the > manipulator > stuff now. The problem is that fixed will be used mostly for monetary conversions. I would probably be upset if I ended up producing an invoice like the following: Bread 1.55 Milk 2.1 Butter 3 I'd really want 2.10 and 3.00 for milk and butter... > Again, the class needs to be careful to avoid unnecessary ambiguity. As > it stands right now, adding a fixed and a longlong is ambiguous, because > either can be converted to the other. Perhaps I should remove the > implicit conversion operators and make everything explicit. I haven't looked at this myself, so this may turn out to be hare-brained. But I think that modeling all of this on the C++ complex type as much as possible would make sense. It's similar in that it is another arithmetic type, and we can be pretty damn sure that whatever the ANSI C++ folks cooked up is really solid. > > Fixed f = "1.11"; > > if (f < 10) > > // ... > > Here there is no problem, since the compiler will correctly use the > Fixed(int) constructor. Yup, forgot about that. > > The last sentence is confusing to me -- I'm not sure exactly what you mean > > here. I think an example would help enormously here. > > Ok: > > // IDL > typedef fixed<5,2> F; > > interface A { > void op(in F arg); > }; > > could map to: > > // C++ > > // either > typedef Fixed F; > > // or > typedef Some_Implementation_Defined_Fixed_Class F; > > class A : public virtual CORBA::Object { > public: > void op(const F &arg); > }; > > The point is that the typedef implicitly defines the digits and scale. > If the parameters don't use the right typedef, then we don't have server > side signature portability. Fine, looks good to me. 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: Thu, 23 Jul 1998 21:50:26 -0700 From: Jonathan Biggar To: Michi Henning CC: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: Michi Henning wrote: > I've forgotten the exact rules for argument matching for > constructors > (which aren't the same as for function arguments...) > > I would suggest to use the C++ complex type as a model -- doing the > same > thing for fixed would probably be the safe and correct way to go. Great suggestion. I'll take a look at the copy of CD2 that I have and see if there is anything useful there. > > > Also, I don't think the text mentions what the behavior should be of > > > converting a Fixed to a LongLong -- does it truncate or round? We should > > > state the behavior. > > > > I could do that better. There is text further on that states that > > arithmetic operations that go out of bounds throw DATA_CONVERSION. > > These should also. > > Yep. But what happens if I convert a fixed<3,2> with value 1.5 to LongLong? > DATA_CONVERSION, rounding, or truncation? Ok, what I mean by out of bounds is if the value is too large on the left. Otherwise, the default is truncation on the right. If you need to round, use round(1,0) function first. > The problem is that fixed will be used mostly for monetary conversions. > I would probably be upset if I ended up producing an invoice like the > following: > > Bread 1.55 > Milk 2.1 > Butter 3 > > I'd really want 2.10 and 3.00 for milk and butter... True. At minimum, perhaps the to_string function should have defaulted field specification arguments. Let me look at the C++ streams stuff again. Perhaps we can make use of the existing field size definitions for floating point. -- 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: Fri, 24 Jul 1998 15:22:39 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) On Thu, 23 Jul 1998, Jonathan Biggar wrote: > > Yep. But what happens if I convert a fixed<3,2> with value 1.5 to LongLong? > > DATA_CONVERSION, rounding, or truncation? > > Ok, what I mean by out of bounds is if the value is too large on the > left. > Otherwise, the default is truncation on the right. If you need to > round, use round(1,0) function first. OK. I think that just needs to be said. > > I'd really want 2.10 and 3.00 for milk and butter... > > True. At minimum, perhaps the to_string function should have > defaulted > field specification arguments. Let me look at the C++ streams stuff > again. Perhaps we can make use of the existing field size > definitions > for floating point. I seem to remember reading an article years ago that showed how to build manipulators for your own data types. Sorry, but I've forgotten the details... I'd be in favour though of not rushing the fixed-type mapping -- if it takes a few more weeks to bed it down, I think that's better than rushing it now and having to hack it up yet one more time. Besides, there doesn't seem to be a great rush of people who want to use fixed point types by yesterday, so I don't think a bit of a delay would hurt. 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-Sender: vinoski@mail.boston.iona.ie Date: Fri, 24 Jul 1998 02:28:55 -0400 To: Michi Henning From: Steve Vinoski Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) Cc: cxx_revision@omg.org References: <35B81292.EA541B13@floorboard.com> At 03:22 PM 7/24/98 +1000, Michi Henning wrote: >I'd be in favour though of not rushing the fixed-type mapping -- >if it takes a few more weeks to bed it down, I think that's better than >rushing it now and having to hack it up yet one more time. Besides, >there doesn't seem to be a great rush of people who want to use fixed point >types by yesterday, so I don't think a bit of a delay would hurt. I voted to accept this because I think what Jon has come up with (modulo a few minor issues) is * implementable, which is the opposite of what we have now * pretty clear, which makes it far more preferable to what we have now * only in need of minor tweaking I feel that we can adopt this because it won't need anything resembling an overhaul -- perhaps a few minor tweaks, but that's it. I am basing this on the fact that someone on my team attempted to prototype the fixed-point junk that is currently in the spec, and he had to redesign it to even get it to work. The redesign that he came up with and Jon's proposal are very similar, and yet were developed independently, so I believe we are well on our way down the right track. I know it seems unusual these days for the OMG to adopt software that's actually been thought about and prototyped, but I feel we should make an exception in this case. :-) --steve Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Fri, 24 Jul 1998 16:39:23 +1000 (EST) From: Michi Henning To: Steve Vinoski cc: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) On Fri, 24 Jul 1998, Steve Vinoski wrote: > I voted to accept this because I think what Jon has come up with (modulo a > few minor issues) is > > * implementable, which is the opposite of what we have now > * pretty clear, which makes it far more preferable to what we have now > * only in need of minor tweaking I'm pretty sure too that what Jon has done is on the right track. > I know it seems unusual these days for the > OMG to adopt software that's actually been thought about and > prototyped, > but I feel we should make an exception in this case. :-) Why break with tradition now? I'm sure I can invent a new mapping for fixed-point types in about five minutes flat, no trouble at all. What's best, I think I can safely guarantee that it won't work in any useful way whatsoever. Perfect OMG specification material... ;-) How about the following suggestion: Jon, could you do a sanity check against the C++ complex type (which I think could be a good model) to see whether what you have is wildly off the mark? If it isn't wildly off the mark, then we just need to make sure what you have now won't clash with what we would consider "ideal". If those conditions are met, I think it would be OK to put the fixed mapping in this time round and flesh it out later. Otherwise, I would prefer to wait, simply because it would be too embarrassing to get it wrong twice in a row... 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, 24 Jul 1998 00:06:57 -0700 From: Jonathan Biggar To: Michi Henning , cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <35B81292.EA541B13@floorboard.com> Jonathan Biggar wrote: > Michi Henning wrote: > > I've forgotten the exact rules for argument matching for > constructors > > (which aren't the same as for function arguments...) > > > > I would suggest to use the C++ complex type as a model -- doing > the same > > thing for fixed would probably be the safe and correct way to go. > > Great suggestion. I'll take a look at the copy of CD2 that I have > and > see if there is anything useful there. Just took a look at complex. It's not very helpful, since it is defined as a template class and only has constructors/conversions from/to that class. > > > > Also, I don't think the text mentions what the behavior should be of > > > > converting a Fixed to a LongLong -- does it truncate or round? We should > > > > state the behavior. > > > > > > I could do that better. There is text further on that states that > > > arithmetic operations that go out of bounds throw DATA_CONVERSION. > > > These should also. > > > > Yep. But what happens if I convert a fixed<3,2> with value 1.5 to LongLong? > > DATA_CONVERSION, rounding, or truncation? > > Ok, what I mean by out of bounds is if the value is too large on the > left. > Otherwise, the default is truncation on the right. If you need to > round, use round(1,0) function first. > > > The problem is that fixed will be used mostly for monetary conversions. > > I would probably be upset if I ended up producing an invoice like the > > following: > > > > Bread 1.55 > > Milk 2.1 > > Butter 3 > > > > I'd really want 2.10 and 3.00 for milk and butter... > > True. At minimum, perhaps the to_string function should have defaulted > field specification arguments. Let me look at the C++ streams stuff > again. Perhaps we can make use of the existing field size definitions > for floating point. Yes, this will work. The fields for controlling floating point are easily accessible: width, precision, flags(fixed vs scientific, uppercase, etc). All I need to do is add text that says that class Fixed uses the same flags & field settings in the stream as floating point, but it never outputs in scientific notation. -- 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: Fri, 24 Jul 1998 17:12:51 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) > > Yes, this will work. The fields for controlling floating point are > easily accessible: width, precision, flags(fixed vs scientific, > uppercase, etc). > All I need to do is add text that says that class Fixed uses the > same > flags & field settings in the stream as floating point, but it never > outputs in scientific notation. Sounds good! Michi. Return-Path: Sender: jon@floorboard.com Date: Fri, 24 Jul 1998 00:11:26 -0700 From: Jonathan Biggar To: Steve Vinoski CC: Michi Henning , cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: <35B81292.EA541B13@floorboard.com> <199807240630.CAA10050@boston.iona.ie> Steve Vinoski wrote: > > At 03:22 PM 7/24/98 +1000, Michi Henning wrote: > >I'd be in favour though of not rushing the fixed-type mapping -- > >if it takes a few more weeks to bed it down, I think that's better > than > >rushing it now and having to hack it up yet one more time. Besides, > >there doesn't seem to be a great rush of people who want to use > fixed point > >types by yesterday, so I don't think a bit of a delay would hurt. > > I voted to accept this because I think what Jon has come up with > (modulo a > few minor issues) is > > * implementable, which is the opposite of what we have now > * pretty clear, which makes it far more preferable to what we have > now > * only in need of minor tweaking > > I feel that we can adopt this because it won't need anything > resembling an > overhaul -- perhaps a few minor tweaks, but that's it. I am basing > this on > the fact that someone on my team attempted to prototype the > fixed-point > junk that is currently in the spec, and he had to redesign it to > even get > it to work. The redesign that he came up with and Jon's proposal are > very > similar, and yet were developed independently, so I believe we are > well on > our way down the right track. I know it seems unusual these days for > the > OMG to adopt software that's actually been thought about and > prototyped, > but I feel we should make an exception in this case. :-) Well, I haven't fully prototyped my proposal, although I have built numeric classes in the past, so I just might have a clue. :-) I have at least compiled the header! I'm going to put out Version 3 incorporating the comments from Steve & Michi tomorrow. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Fri, 24 Jul 1998 08:32:53 -0700 From: Jonathan Biggar To: Michi Henning CC: Steve Vinoski , cxx_revision@omg.org Subject: Re: Version 2 of proposal to "fix" fixed point in the C++ mapping :-) References: Michi Henning wrote: > How about the following suggestion: Jon, could you do a sanity check > against the C++ complex type (which I think could be a good model) > to see > whether what you have is wildly off the mark? If it isn't wildly off > the > mark, then we just need to make sure what you have now won't clash > with > what we would consider "ideal". As I alluded to last night, I took a look at the public comment draft 2 version of the C++ standard (the latest I have available to me), and there was nothing in the C++ Complex type that was very useful to the Fixed point class, because it is defined as a template type and only provides construction/conversion from/to that single type. However, there also wasn't anything there that suggested that I am on the wrong track either. > If those conditions are met, I think it would be OK to put the fixed > mapping in this time round and flesh it out later. Otherwise, I > would > prefer to wait, simply because it would be too embarrassing to get > it > wrong twice in a row... We just got an affirmation from Steve++ that the "fixed" fixed point that was developed at IONA was quite similar to my proposal, so we have at least one data point where something was implemented using an interface quite like the one I propose. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: Sender: jon@floorboard.com Date: Fri, 24 Jul 1998 14:52:37 -0700 From: Jonathan Biggar To: cxx_revision@omg.org Subject: Version 3 of proposal to "fix" fixed point in the C++ mapping :-) [This is version 3 of the fixed point mega-proposal. I have made the following changes: A. I have tightened up the language for the iostream extraction & insertion operators. I have added text that states that the exact version of these should be what is appropriate for the C++ environment. I have also added text that states that formatted fixed input & output is driven by the same format specifiers as for floating-point. B. I have dropped the to_string() function, because using a strstream and inserting a Fixed value gives the programmer more control over the format. C. I added an example of a fixed point constant mapped to C++. D. I have added text clarifying how the conversion from Fixed to other types handles out of bounds cases and truncation when converting to an integral type. E. I have added an example of the mapping to clarify the text requiring the use of the typedef name to make sure that server side signatures are portable. I don't think any of these changes (except perhaps for B) should be considered as substantially modifying the proposal, they are just clarifications and language tightening.] This proposal addresses the following issues: Issue 1056: Fixed types in orbos/98-01-11 Issue 1069: Typos on p 20-34 of orbos/98-01-11 Issue 1070: macros for fixed arithmetic results Issue 1072: fixed_digits and fixed_scale member functions Issue 1073: Missing constructor for Fixed Issue 1092: C++ mapping for fixed is broken (01) Issue 1093: C++ mapping for fixed is broken (02) Issue 1124: C++ Fixed type issue (01) Issue 1125: Fixed type (02) Issue 1126: C++ Fixed Type (03) Issue 1538: Missing text describing fixed point constant mapping Summary description of the problems with fixed: The worst problem with the existing CORBA 2.2 mapping for fixed point types is the attempted use of a template type with the digits and scale as template arguments. This causes two major problems, neither of which is possible to fix without reworking the mapping entirely. The first is that the Fixed is defined as a template in the CORBA namespace. This cannot be implemented in a compiler that does not support either namespaces or member templates. Since there are still quite a few compilers with this deficiency, this is a bad idea for a fundamental type. The second problem is that the arithmetic for fixed point types (particularly the divide operation) defines the digits and scale of the result of binary mathematics operations (+, -, *, /) to depend on the runtime values of the arguments. This cannot be expressed using C++ template declarations, since the digits and scale must be compile time constants. The second problem area with the fixed point mapping is that the mapping totally ignores fixed point constant declarations and how to map them into C++. For an IDL fixed point declaration: const fixed foo = 1.2D; neither the use of the keyword "fixed" without digits and scale parameters, nor the actual fixed point literal, "1.2D" have a mapping into C++. The third major problem area has to do with the IDL grammar itself. The CORBA 2.2 grammar allows fixed point types to be defined anonymously (without a typedef) as IDL operation parameters or return types. But since the C++ mapping specifies that _var and _out types are defined for anonymous fixed point types, this causes two problems: first, the mapping does not define how to handle a negative scale when determining the name for the _var and _out types for an anonymous fixed point type, and second, there is no clear place to define the _var and _out types when an anonymous fixed point type is used as an IDL parameter or return type. Overview of the Proposal: The key to the proposal is to redefine CORBA::Fixed to be a non-template type that can handle any combination of digits and scale at run time. All of the arithmetic operations are defined using CORBA::Fixed. However, this proposal does not require that CORBA::Fixed be used as the type for operation parameters and fields in IDL structured types (struct, union, sequence, array, etc). The reason for this is that a generic fixed point value needs about 18 bytes of storage, minimum--16 for the 31 digits plus sign, 2 for the digits and scale values. So, by allowing the implementation to choose to use another type for fixed point types with an explicit digits and scale, this gives the implementation the flexibility to reduce the storage cost for fixed point types in places where the digits and scale are known. It also allows the implementation to code the bounds check for digits and scale into the conversion between the "generic" CORBA::Fixed type and the actual type used for operation parameters and structured members, rather than having to add code at runtime to check these bounds inside the marshaling engine. In fact, an implementation could still use a template for these unnamed types without the problems described above, since the implementation is free to declare the template however it needs to. The second problem, that the mapping for fixed point constants is not specified, is solved by mapping fixed point constants to normal C++ string literals. The third problem, issues with declaring _out & _var types for fixed point has been mainly resolved by the ORB core RTF, which has already approved a fix that obviate the need for the C++ RTF to fix these problems. The proposal accepted by the core RTF are to forbid the declaration of anonymous fixed types as IDL operation parameters. In addition, the proposal presented here eliminates the _var type for fixed point types, because it is unnecessary. This proposal just treats C++ fixed point types like built-in C++ types. Since a maximal sized fixed point type needs little if any more storage than a long double, which is passed by value, there isn't much need to use dynamic storage (new and delete) for fixed point values. Besides, the C++ mapping specifies that fixed point types are always passed by reference, and never by pointer. The ORB core RTF has also passed a proposal that outlaws the use of a negative scale, since the original CORBA 2.2 specification stated that this was not portable anyway. Proposal: Make the following changes to the CORBA 2.2 C++ mapping (section 20): -------------------------------------------------------------------------------- Add the following paragraphs to the end of section 20.4: Fixed Point Constants Since C++ does not have a native fixed point type, IDL fixed point literals are mapped to C++ strings without the trailing 'd' or 'D' in order to guarantee that there is no loss of precision. For example: // IDL const fixed F = 123.456D; // C++ const Fixed F = "123.456"; -------------------------------------------------------------------------------- Replace the entire text of section 20.11 with: 20.11 Mapping for Fixed The C++ mapping for fixed is defined by the following class: class Fixed { public: // Constructors... Fixed(int val = 0); Fixed(unsigned val); Fixed(Long val); Fixed(ULong val); Fixed(LongLong val); Fixed(ULongLong val); Fixed(Double val); Fixed(LongDouble val); Fixed(const Fixed& val); Fixed(const char *); ~Fixed(); // Conversions... operator LongLong() const; operator LongDouble() const; Fixed round(UShort digits, UShort scale) const; Fixed truncate(UShort digits, UShort scale) const; // Operators... Fixed& operator=(const Fixed& val); Fixed& operator+=(const Fixed& val); Fixed& operator-=(const Fixed& val); Fixed& operator*=(const Fixed& val); Fixed& operator/=(const Fixed& val); Fixed& operator++(); Fixed& operator++(int); Fixed& operator--(); Fixed& operator--(int); Fixed& operator+() const; Fixed& operator-() const; int operator!() const; // Other member functions UShort fixed_digits() const; UShort fixed_scale() const; }; istream& operator>>(istream& is, Fixed &val); ostream& operator<<(ostream& os, const Fixed &val); Fixed operator + (const Fixed &val1, const Fixed &val2); Fixed operator - (const Fixed &val1, const Fixed &val2); Fixed operator * (const Fixed &val1, const Fixed &val2); Fixed operator / (const Fixed &val1, const Fixed &val2); Fixed operator > (const Fixed &val1, const Fixed &val2); Fixed operator < (const Fixed &val1, const Fixed &val2); Fixed operator >= (const Fixed &val1, const Fixed &val2); Fixed operator <= (const Fixed &val1, const Fixed &val2); Fixed operator == (const Fixed &val1, const Fixed &val2); Fixed operator != (const Fixed &val1, const Fixed &val2); The Fixed class is used directly by the C++ mapping for IDL fixed point constant values and for all intermediate results of arithmetic operations on fixed point values. For fixed point parameters of IDL operations or members of IDL structured datatypes, the implementation may use the Fixed type directly, or alternatively, may use a different type, with an effectively constant digits and scale, that provides the same C++ interface and can be implicitly converted from/to the Fixed class. The name(s) of this alternative class is not defined by this mapping. Since fixed point types used as parameters of IDL operations must be named via an IDL typedef declaration, the mapping must use the typedef to define the type of the operation parameter to make sure that server side operation signatures are portable. Here is an example of the mapping: // IDL typedef fixed<5,2> F; interface A { void op(in F arg); }; // C++ typedef Implementation_Defined_Class F; class A { public: ... void op(const F &arg); ... }; The Fixed class has a number of constructors to guarantee that a fixed value can be constructed from any of the IDL standard integer and floating point types. The Fixed(char *) constructor converts a string representation of a fixed point literal into a real fixed point value, with the trailing 'd' or 'D' optional. The Fixed class also provides conversion operators back to the LongLong and LongDouble types. For conversion to integral types, digits to the right of the decimal point are truncated. If the magnitude of the fixed point value does not fit in the target conversion type, then the DATA_CONVERSION system exception is thrown. The round() and truncate() functions convert a fixed value to a new value with the specified digits and scale. If the new digits and scale require the value to loose precision on the right, the round() function will round away from zero values that are halfway or more to the next absolute value for the new fixed precision. The truncate() function always truncates the value towards zero. So, for example: Fixed f1 = "0.1"; Fixed f2 = "0.05"; Fixed f3 = "-0.005; f1.round(1,0) and f1.truncate(1,0) both return 0., f2.round(2,1) returns 0.1, f2.truncate(2,1) returns 0.0, f3.round(3,2) returns -0.01 and f3.truncate returns 0.00. The fixed_digits() and fixed_scale() functions return the smallest digits and scale value that can hold the complete fixed point value. If the implementation uses alternative classes for operation parameters and structured type members, then fixed_digits() and fixed_scale() return the constant digits and scale values defined by the source IDL fixed point type. Arithmetic operations on the Fixed class must calculate the result exactly, using an effective double precision (62 digit) temporary value. The results are then truncated at run time to fit in a maximum of 31 digits using the method defined in 3.7.2 to determine the new digits and scale. If the result of any arithmetic operation produces more than 31 digits to the left of the decimal point, the DATA_CONVERSION exception will be thrown. If a fixed point value, used as an actual operation parameter or assigned to a member of an IDL structured datatype, exceeds the maximum absolute value implied by the digits and scale, the DATA_CONVERSION exception will be thrown. The stream insertion and extraction operators << and >> convert a fixed point value to/from a stream. The exact definition of these operators may vary depending on the level of standardization of the C++ environment. These operators insert and extract fixed point values into the stream using the same format as for C++ floating point types. In particular, the trailing d or D from the IDL fixed point literal representation is not inserted or extracted from the stream. These operators use all format controls appropriate to floating point defined by the stream classes except that they never use the scientific format. 20.11.1 Fixed T_var and T_out Types Since fixed point types are always passed by reference as operation parameters and returned by value, there is no need for a _var type for fixed point. For each IDL fixed point typedef a corresponding _out type is defined as a reference to the fixed point type: // IDL typedef fixed<5,2> F; // C++ typedef Implementation_Defined_name F; typedef F &F_out; -------------------------------------------------------------------------------- In section 20.16.2, change the paragraph that reads: For values of type T that are too large to be passed by value efficiently, such as structs, unions, sequences, fixed types, Any, and exceptions, two forms of the insertion function are provided. to: For values of type T that are too large to be passed by value efficiently, such as structs, unions, sequences, Any, and exceptions, two forms of the insertion function are provided. -------------------------------------------------------------------------------- In section 20.16.3, change the paragraph that reads: "For non-primitive types, such as struct, union, sequence, exception, Any, and fixed types, extraction is done by pointer. For example, consider the following IDL struct:" to: For non-primitive types, such as struct, union, sequence, exception, and Any, extraction is done by pointer. For example, consider the following IDL struct: -------------------------------------------------------------------------------- Changed the title of section 20.16.4 to: 20.16.4 Distinguishing boolean, octet, char, wchar, bounded string, bounded wstring and fixed Change the first paragraph to: Since the boolean, octet, char, and wchar OMG IDL types are not required to map to distinct C++ types, another means of distinguishing them from each other is necessary so that they can be used with the type-safe any interface. Similarly, since both bounded and unbounded strings map to char*, both bounded and unbounded wide strings map to WChar*, and all fixed point types map to FixeD, another means of distinguishing them must be provided. This is done by introducing several new helper types nested in the any class interface. Add the following declaration to the Any class right after the corresponding from_wstring/to_wstring references: struct from_fixed { from_fixed(const Fixed &f, UShort d, UShort s) : val(f), digits(d), scale(s) { } const Fixed &val; UShort digits; UShort scale; }; void operator <<=(from_fixed); struct to_fixed { to_fixed(Fixed &f, UShort d, UShort s); Fixed &val; UShort digits; UShort scale; }; void operator >>=(to_fixed) const; Also add these declarations to the Any class in section 20.39.4. Add the following to the end of the example on page 20.54: Fixed f = "123.45"; any <<= Any::from_fixed(f, 5, 2); // ... if (any >>= Any::to_fixed(f, 5, 2)) { // ...any contains a fixed<5,2> } -------------------------------------------------------------------------------- Change the fixed point type row in Table 20-2 to: fixed const Fixed & Fixed & Fixed & Fixed -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org