Spit a Decimal Value

souravb
Member Posts: 135
Hi,
I have a decimal field amount having value say 35.65.
I want to separate the left and right parts of the decimal and show in different fields. How to do that?.
I have a decimal field amount having value say 35.65.
I want to separate the left and right parts of the decimal and show in different fields. How to do that?.
1
Comments
-
Left := selectstr(1,format(dec)); //Left is a textvariable
right := selectstr(2,format(dec)); //right is a text variable
RegardsDo you make it right, it works too!0 -
Or if you need as integer then:
Amount := 35.65; IntAmount := amount div 1; DecAmount := amount * 100 / mod 100;
David Singleton0 -
evaluate(Left,selectstr(1,format(dec))) ; //Left is a decimal, text, integer, code evaluate(right,selectstr(2,format(dec))) ; //right is a decimal, text, integer, code
0 -
Hmmm both viable solutions....now I wonder which one would perform better?
I would think that the pure math operations (i.e. div/mod solution) would perform better as it doesn't need to translate to & from strings which I think should take longer.0 -
jlandeen wrote:Hmmm both viable solutions....now I wonder which one would perform better?
I would think that the pure math operations (i.e. div/mod solution) would perform better as it doesn't need to translate to & from strings which I think should take longer.
Although you are correct that it should be faster, that was not my prime concern. But there are more important reasons to consider also.
Firstly code needs to be readable. There is no need to write complex code that is confusing, KISS. Secondly the code needs to work in all environments. For example try this codeMyDecimal := 12345.67; Left := selectstr(1,format(MyDecimal)); right := selectstr(2,format(MyDecimal)); message('Left = %1 \ Right = %2',left,right); --------------------------- Microsoft Dynamics NAV --------------------------- Left = 12 Right = 345.67 --------------------------- OK ---------------------------
As you can see Left is 12 and right is 345.67 I think that is the wrong answer.Amount := 12345.67; IntAmount := amount div 1; DecAmount := amount * 100 mod 100; message('IntAmount = %1 \ DecAmount = %2',intamount,decamount); --------------------------- Microsoft Dynamics NAV --------------------------- IntAmount = 12345 DecAmount = 67 --------------------------- OK ---------------------------
Why the difference?
Simple the format command is not really designed for manipulating text, it is designed for presenting text. To use the format command in a case like this you need to know the exact conditions, such as the Regional settings of the computer.
Also the most important issue here (and why I am giving a detailed reply) is that the original post is very badly written. It does not explain WHAT they user is trying to achieve, just HOW they want to do it.
Is the objective just for formatting on a report, or are the results to be used somewhere else. There may be many better solutions, and maybe none involving manipulation of the source number.
So posters need to be more clear in what they ask, or they will not get the best solution.David Singleton0 -
You're absolutely right that responses can be much improved if the original question/post is detailed & clear (although I do understand that some users can struggle with English not being their first language).
Until you're post I didn't see that problem with the selectstr command. It only works if a comma is used as a decimal seperator (there are some locales that do that). So for other locations that use a comma (,) as a thousands separator and a period (.) character as a decimal separator the following code would work - but as pointed out above, the KISS method should be followed and this code is more for discussion/demonstration:code: MyDecimal := 12345.67; TextDecimal := DELCHR(FORMAT(MyDecimal),'=',','); DecimalPosition := STRPOS(TextDecimal,'.'); Left := COPYSTR(TextDecimal,1,DecimalPosition - 1); Right := COPYSTR(TextDecimal,DecimalPosition + 1); MESSAGE('Left = %1\Right = %2',Left,Right); Result: --------------------------- Microsoft Dynamics NAV --------------------------- Left = 12345 Right = 67 --------------------------- OK ---------------------------
0 -
Thnx David for your detail reply.
..................................
HI Sourav..try this code...
MyDec := 11111112.23564
Pos := STRPOS(FORMAT(MyDec),'.');
Length := STRLEN(FORMAT(MyDec));
IntPart :=COPYSTR(FORMAT(MyDec),1,(Pos-1));
DecPart :=COPYSTR(FORMAT(MyDec),(Pos+1),Length- Pos+1);Now or Never0 -
If you are going with the FORMAT method why not just use a format string that returns just the integer and decimal portions of the number?
FORMAT(Amount,0,'<Integer>') FORMAT(Amount,0,'<Decimals>')
If you are interested in the math approach keep in mind that the MOD function can be used with decimals and it is not necessary to scale the amount by 100 (or some other power of 10).DecAmount := Amount mod 1;
0 -
jreynolds wrote:If you are interested in the math approach keep in mind that the MOD function can be used with decimals and it is not necessary to scale the amount by 100 (or some other power of 10).
DecAmount := Amount mod 1;
The " * 100 " was not to scale it, it was to achieve the request of the user, i.e. to split the LEFT and RIGHT parts of the decimal. If you don't multiply by 100 then the RIGHT part will be 0.35 rather than that 35 as requested. 8)David Singleton0 -
navuser1 wrote:Thnx David for your detail reply.
..................................
HI Sourav..try this code...
MyDec := 11111112.23564
Pos := STRPOS(FORMAT(MyDec),'.');
Length := STRLEN(FORMAT(MyDec));
IntPart :=COPYSTR(FORMAT(MyDec),1,(Pos-1));
DecPart :=COPYSTR(FORMAT(MyDec),(Pos+1),Length- Pos+1);
You gotta be kidding.
is this a competition to see who can do this with the most lines of code?
I am visualizing now a loop, with an embedded case statement, and an array of 100 CHAR.David Singleton0 -
jreynolds wrote:If you are going with the FORMAT method why not just use a format string that returns just the integer and decimal portions of the number?
FORMAT(Amount,0,'<Integer>') FORMAT(Amount,0,'<Decimals>')
I really don't like using FORMAT in situations like this, but IF it had to be using FORMAT, then I agree that this is the better solution.David Singleton0 -
Even if you have a comma as delimiter symbol, SELECTSTR also won't work if the integer part and the decimal places part is equal.
MyDecimal := 67.67; Left := selectstr(1,format(MyDecimal)); Right := selectstr(2,format(MyDecimal)); message('Left = %1 \ Right = %2',left,right);
I triedFORMAT(Amount,0,'<Integer>') FORMAT(Amount,0,'<Decimals>')
That's a pretty good solution. But I get the delimiter symbol as first sign of "Right". So, I guess it should be something likeFORMAT(Amount,0,'<Integer>') COPYSTR(FORMAT(Amount,0,'<Decimals>'),2)
Shouldn't it?"Money is likewise the greatest chance and the greatest scourge of mankind."0 -
I am just curious, do you programmers get paid by the line?
Why not just use the simplest solution that works? [-o<
David Singleton0 -
Maybe because
Amount := 12345.67; IntAmount := amount div 1; DecAmount := amount * 100 mod 100; message('IntAmount = %1 \ DecAmount = %2',intamount,decamount);
will only work if you have exactly 2 decimal places :?: Or I am wrong in my understanding of DIV and MOD..."Money is likewise the greatest chance and the greatest scourge of mankind."0 -
The solution with Mod & Div should work regardless of the number of decimal places. If you needed to only have n significan digits in the decimal place you could simply use the Round function on the decimal value before it's used by mod & div operators.
Once again this thread proves there are many ways to get things done.0 -
When I test with
Amount := 12345.6789; IntAmount := amount div 1; DecAmount := amount * 100 mod 100; message('IntAmount = %1 \ DecAmount = %2',intamount,decamount);
I get
Microsoft Dynamics NAV
IntAmount = 12.345
DecAmount = 67,89
OK
When I test withAmount := 12345.6; IntAmount := amount div 1; DecAmount := amount * 100 mod 100; message('IntAmount = %1 \ DecAmount = %2',intamount,decamount);
I get
Microsoft Dynamics NAV
IntAmount = 12.345
DecAmount = 60
OK
In some cases you need the exact integer value, so this solution wouldn't help."Money is likewise the greatest chance and the greatest scourge of mankind."0 -
Can you help me please, I need to get my decimal value like this:
Amount := 12.5; AmountSent := 12,5;
Regards
Hanen TALBI0 -
Hanen wrote:Can you help me please, I need to get my decimal value like this:
Amount := 12.5; AmountSent := 12,5;
If you just need the conversion for sending data (textual)AmountToSend := CONVERTSTR(FORMAT(Amount),'.',',');
( Oh and by the way, you may want to create a new thread instead of hijacking someone elses )0 -
there is one issue that in thausand are separated by comma.
So you have to convert the Comma to a '~' for example first
then convert dot to comma, then convert ~ to decimal.AmountToSend := CONVERTSTR(FORMAT(Amount),',','~'); AmountToSend := CONVERTSTR(FORMAT(Amount),'.',','); AmountToSend := CONVERTSTR(FORMAT(Amount),'~','.');
so
1,000.00 would turn to 1.000,000 -
ara3n wrote:there is one issue that in thausand are separated by comma.
So you have to convert the Comma to a '~' for example first
then convert dot to comma, then convert ~ to decimal.AmountToSend := CONVERTSTR(FORMAT(Amount),',','~'); AmountToSend := CONVERTSTR(FORMAT(Amount),'.',','); AmountToSend := CONVERTSTR(FORMAT(Amount),'~','.');
so
1,000.00 would turn to 1.000,00AmountToSend := CONVERTSTR(FORMAT(Amount,0,'<Integer><Decimals,3>'),'.',',');
How's that?0 -
einsTeIn.NET wrote:I get
Microsoft Dynamics NAV
IntAmount = 12.345
DecAmount = 67,89
OK
Looks to me that your locale is set up to use periods as thousand separators and commas as decimal separators. Try including amount in your message output - I'm sure you'll see it displayed as 12.345,6789.einsTeIn.NET wrote:When I test withAmount := 12345.6;
(...)
I get
Microsoft Dynamics NAV
IntAmount = 12.345
DecAmount = 60
OK
In some cases you need the exact integer value, so this solution wouldn't help.
I agree: if the decimal part has non-significant digits in the precision you want (e.g. 2, in this case), they will become significant digits if multiplied by 10^precision. (0.60 will become 60, rather than 6). Or, if you want all the digits, and not just 2, then if course it doesn't work.
For either, one solution would be to multiply the decimals by 10 until you reach the end of the decimal string.amount := -12345.6789; IntAmount := amount div 1; DecAmount := ABS(amount - IntAmount); WHILE (DecAmount <> DecAmount div 1) DO DecAmount := DecAmount * 10; // Thankfully (with SQL Server at least), the Decimal type has a fixed-point precision, so it will always end eventually DecAmount := DecAmount div 1; message('IntAmount = %1 \ DecAmount = %2',intamount,decamount);
Microsoft Dynamics NAV
IntAmount = -12 345
DecAmount = 6 789
OK
Another solution (sorry David) would be to use the FORMAT function on the decimal part in a manner that is controlled and makes it locale-independant.
amount := -12345.6789; IntAmount := amount div 1; IF (amount <> IntAmount) THEN EVALUATE(DecAmount, COPYSTR(FORMAT(ABS(amount - IntAmount)), 3)); // Skip first 2 characters (should be "0," or "0.") message('IntAmount = %1 \ DecAmount = %2',intamount,decamount);
Still not "one-line-elegant", but this operation probably cannot be carried out with code that is much smaller than the above yet remain fully portable, readable and efficient all at the same time. ("Pretty, good, cheap: choose two.")
Both solutions above work with negatives as well. And they could easily be modified to add an arbitrary Precision.0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions