Welcome to MSDN Blogs Sign in | Join | Help

How to fill in that number grouping member of NUMBERFMT

If you look at the NUMBERFMT structure, the way groups are expressed by the Grouping member do not match the value returned by LOCALE_SGROUPING:

LOCALE_
SGROUPING
Grouping Sample Culture
3;0 3 1,234,567 United States
3;2;0 32 12,34,567 India
3 30 1234,567 (none I know of)

LOCALE_SGROUPING expresses grouping as a series of semicolon-separated numbers, each expressing the number of digits in each group (least-significant group first). A trailing zero indicates that the last grouping should be repeated indefinitely. For example, "3;2;0" means "Group the three least significant digits, then in twos until you run out of digits." If there is no trailing ";0", then there are no commas past that point. For example, "3" means "Group the three least significant digits, then stop."

The Grouping member expresses the grouping rules differently. Each significant digit represents a group, with the most significant digit representing the least-significant group, with the units digit repeated indefinitely. For example, "32" means "make a group of three digits, then group by twos thereafter." To suppress the repetition, multiply by ten.

In other words, the two systems are basically the same, with the Grouping consisting of the LOCALE_SGROUPING string with the semicolons removed. Except that the meaning of the trailing zero is reversed, so if LOCALE_SGROUPING has a trailing zero, you have to remove it to get the Grouping, and if it lacks a trailing zero, then you have to add one to the Grouping.

It's kind of strange that the two systems differ, considering that they both came from the same NLS team! It's probably a case of parallel evolution, wherein the locale-string folks and the number-formatting folks came up with their respective systems independently.

Writing code to implement this conversion from LOCALE_SGROUPING to Grouping shouldn't be hard once you understand the algorithm, so I'll leave that as an exercise.

Fortunately, in real life you rarely have need to perform this conversion, for you can just pass the desired locale as the first parameter to the GetNumberFormat (or even better, LOCALE_USER_DEFAULT), pass a NULL pointer as the lpNumberFormat, and let NLS do all the work.

Published Tuesday, April 18, 2006 7:00 AM by oldnewthing
Filed under:

Comments

# Grouping in the managed and unmanaged worlds

Tuesday, April 18, 2006 12:03 PM by Sorting It All Out
Yesterday, when I talked about that post from Raymond about numeric grouping the locale sensitive way,...

# re: How to fill in that number grouping member of NUMBERFMT

Tuesday, April 18, 2006 12:24 PM by Daev
Are there cultures that group decimal digits on the right-hand side of the decimal point as well?

For instance:  3.141,592,635,5

# re: How to fill in that number grouping member of NUMBERFMT

Tuesday, April 18, 2006 9:49 PM by Norman Diamond
Tuesday, April 18, 2006 12:24 PM by Daev
> Are there cultures that group decimal digits
> on the right-hand side of the decimal point
> as well?

I wouldn't call it a culture, but I saw that in some old ACM articles a few times.  It took a moment to get used to it.

A bit more frequently I've seen spaces on the right-hand side of the decimal point.

# re: How to fill in that number grouping member of NUMBERFMT

Wednesday, April 19, 2006 3:24 AM by strik
I find it puzzling that Windows insists on formatting for Germany like "1.234.567,89" (cf. http://blogs.msdn.com/oldnewthing/archive/2006/04/17/577483.aspx). Although this is the "official" way to do it, from experience, almost no-one uses this scheme when hand-writing. Rather, the dots are replaced by spaces (thus, "1 234 567,89". Much more interesting, some people really have problems if they got values with dots ("1.234" will be treated as 1 + 234/1000 instead of 1234 by many people I know).

For example, I have yet to see any school teaching writing the dots for separating thousands; it is always a small space between the groups.

Is there anyone out there who feels the same like me?

# In Germany (elsewhere, too, probably)

Wednesday, April 19, 2006 4:28 AM by Goran
"1.234" will be treated as 1 + 234/1000 instead of 1234 by many people I know"

Probably wasn't the case before computers (with programs that don't cater for different locales).

Example: when I was in school, we wrote dates like this: 21. VI 2006 (june 21st, 2006). It's rarely done now. I don't think it's even possible to do it with computers. Pitty, no?

# re: How to fill in that number grouping member of NUMBERFMT

Thursday, April 20, 2006 9:39 AM by Mark Steward
Goran: here you go!  This is in PHP, as the C++ equivalent is about 20 lines. Requires a font with the appropriate codepoints.

<font face="Arial Unicode MS">
<?php
 echo date('j') . '. &#' . (intval(date('n')) + 0x215f) . '; ' . date('Y');
 // Use 0x216f for lowercase roman numerals.  And date('n') should be checked for errors.
?>
</font>

# re: How to fill in that number grouping member of NUMBERFMT

Thursday, April 20, 2006 8:15 PM by Mark Steward
Ahem.  I feel a bit dirty posting PHP here, even on a silly hack, so:

DateTime Now = DateTime.Now;
string Month = (Now.Month < 1 || Now.Month > 12) ? "MM" : "'" + (char)(0x215f + Now.Month) + "'";
string Date = Now.ToString("dd'.' " + Month + " yyyy");

Not suggesting that anybody *does* this, of course...

Although it suddenly occurs to me that you could get the same effect by putting the roman numerals as the "short name" for a month (perhaps the ELKs could help).

# re: How to fill in that number grouping member of NUMBERFMT

Saturday, April 22, 2006 7:27 PM by me
[...] like "1.234.567,89" (cf. http://blogs.msdn.com/oldnewthing/archive/2006/04/17/577483.aspx). Although this is the "official" way to do it [...]

German standard DIN 5008:2001 clearly says to write numbers like "1 234 567,89". Only amounts of money should be written "1.234.567,89 EUR".

# Steven Engelhardt &raquo; Blog Archive &raquo; Generating and Parsing Localized Numbers In Windows

New Comments to this post are disabled
 
Page view tracker