Numeric-format for STRING(DECIMAL)

Posted by Lieven De Foor on 27-Mar-2018 02:54

Is there a way to specify the numeric format when storing a DECIMAL as STRING?

Currently, using the STRING() function on a DECIMAL uses the session's numeric format to store the value, which creates a value that is not session independent.

Is there a way to store a decimal in a string using a specific numeric format, or a numeric format independent way?

Posted by Lieven De Foor on 27-Mar-2018 03:21

Answering myself.

DEFINE VARIABLE Pi AS DECIMAL NO-UNDO INITIAL 3.14159.

DEFINE VARIABLE PiString AS CHARACTER NO-UNDO.

/* Store as American format decimal string */

ASSIGN PiString = REPLACE(STRING(Pi), SESSION:NUMERIC-DECIMAL-POINT, ".":U).

/* Restore as decimal */

ASSIGN Pi = DECIMAL(REPLACE(PiString, ".":U, SESSION:NUMERIC-DECIMAL-POINT)).

All Replies

Posted by Lieven De Foor on 27-Mar-2018 03:21

Answering myself.

DEFINE VARIABLE Pi AS DECIMAL NO-UNDO INITIAL 3.14159.

DEFINE VARIABLE PiString AS CHARACTER NO-UNDO.

/* Store as American format decimal string */

ASSIGN PiString = REPLACE(STRING(Pi), SESSION:NUMERIC-DECIMAL-POINT, ".":U).

/* Restore as decimal */

ASSIGN Pi = DECIMAL(REPLACE(PiString, ".":U, SESSION:NUMERIC-DECIMAL-POINT)).

Posted by Thomas Mercer-Hursh on 27-Mar-2018 09:11

One might observe that this is exactly why one should store a decimal as a decimal.

Posted by Lieven De Foor on 27-Mar-2018 09:17

In the end a conversion always happens at one point or another when outputting/reading to/from file/json/xml/... so keeping as decimal can only be done to a certain extent...

Posted by Thomas Mercer-Hursh on 27-Mar-2018 11:52

Yes, but those are all I/O operations where one expects to have to do such things.  If a field is conceptually decimal, it should be stored as a decimal.

Posted by gus bjorklund on 27-Mar-2018 15:24

Values of all 4GL datatypes are stored in the database (and in 4GL runtime's local memory) in a format neutral and processor architecture neutral form. The supported numeric types are integer, decimal and float and each has its own storage format.

The values of type decimal are stored as a string of 4-bit “nibbles” preceded by a length byte and a "control byte”. Each nibble represents one digit of the value.

The control byte is, if negative, the number of digits to the right of the decimal point. If positive, then digits to the left of the decimal point + 0x80. The maximum number of digits is 32.

The display format has nothing at all to do with the storage format. This is a good thing. You should store decimal values as a value of type decimal, not something else like string.

When converting values from decimal storage to text, use whatever format is suitable for your intended use.

Posted by jquerijero on 27-Mar-2018 15:57

I think he is receiving an American XML and processing it on a European computer in which a string representation of a decimal value has to be converted to the proper region first before it can be stored correctly. 

[quote user="Thomas Mercer-Hursh"]

Yes, but those are all I/O operations where one expects to have to do such things.  If a field is conceptually decimal, it should be stored as a decimal.

[/quote]

Posted by Thomas Mercer-Hursh on 27-Mar-2018 16:37

The OP said "Is there a way to specify the numeric format when storing a DECIMAL as STRING?"  I read that as *storing decimal as string*, not an I/O conversion operation.

Posted by Lieven De Foor on 28-Mar-2018 01:38

jquerijero's answer disappeard, but I got it by mail:

[quote user="jquerijero"]

I think he is receiving an American XML and processing it on a European computer in which a string representation of a decimal value has to be converted to the proper region first before it can be stored correctly.

[/quote]

Off course for regular use a decimal value is stored in a decimal variable/decimal field, that's not the discussion/point here, that is obvious.

By storing I meant in a character variable. That variable could contain more than just the single decimal. This variable could be stored in a db character field, containing arbitrary data, or to a file, or sent through a socket...

Posted by Lieven De Foor on 28-Mar-2018 01:47

[quote user="gus bjorklund"]

When converting values from decimal storage to text, use whatever format is suitable for your intended use.

[/quote]
Well that's the issue, you can't specify the decimal separator for the STRING() function. You get the string value in the current numeric-format setting, using the sessions decimal point, and need to do a replace to get something fixed.
I have a workaround, which is fine for me, but a built-in way would have been nice...

Posted by Thomas Mercer-Hursh on 28-Mar-2018 09:06

You could easily put the stringification in a function and set the desired session format there or do the replacements there, but I guess I have to wonder why, if the current function is intended to have a particular format, you don't just set the session format for the whole thing.  I..e., the format is part of the context.

Posted by Lieven De Foor on 29-Mar-2018 02:14

Hi Thomas,

Yes, I've added the code in a helper class method to do the replacement.

The whole idea is that the string can be read/written in sessions that have different numeric-format settings. I won't force some setting to the session of the user, people in Europe want to use comma's instead of points as decimal separator.

This thread is closed