Answered by:
How to test last two digits in decimal variables with different precisions

I've got a decimal variable with a currency rate that can come in one of two ways; if it's about Yen then the value will be something like 110.50 or 110.00, but if it's about most any other currency rate it will be something like 0.7100 or 0.7050.
I need to figure out in code whether the order is a "50 or a 100" referring to the two last digits. What's the smart way of doing this?
TIA
Dennis
Question
Answers

int _0th=decimal.GetBits(yourDecimalNumber)[0]; bool b100=_0th%100==0,b50=_0th%50==0; Console.WriteLine("ENDS WITH {0}",b100?"00":b50?"50":"none");
ISN'T THE SMART CODE RIDICULOUSLY SIMPLE?
It is just a matter of implementing it using C# and not rubbish#...
▪
 Marked as answer by sgude1 Friday, March 31, 2017 7:35 PM
Friday, March 31, 2017 7:29 PM
All replies

What you're referring to as the precision is only the stringbased representation you may be seeing. Under the hood that value could potentially be different. Also note that you said the last 2 digits but 100 is 3 digits. So my first question would be what format are you getting the original value in  string, decimal, etc? If it is a string then you should probably do your processing before converting to a decimal.
However if it is a decimal then you'll likely want to round the value to the precision you want first. For example if you want to ensure that you're only dealing with 3 digits of precision to the right of the decimal then use Math.Round. That would normalize your value so you could now look at the values consistently (.500 or .000 or .710 or .705).
Ideally if you can solve this problem by simply using ranges of values then it would probably be better. For example if you want to know whether a value is 0.7100 vs 0.7050 then it would be easier to use range checking like (x >= 0.700 && x < 0.7100). Ignoring rounding concerns this would give you what you want.
If you really need the fractional parts as is then you're best bet is to probably simply convert it to a string with the specifier to force a certain precision range. Then you can grab everything to the right of the decimal. But given rounding issues and whatnot I'm not sure the results will be what you want unless you can be sure of the format(s) you're going to be getting.
Perhaps if you could clarify why you need to do this we can provide better suggestions.
Michael Taylor
http://www.michaeltaylorp3.net

These are currency rates, and they come in two versions, four decimals for nonyen pairs, and two decimal for all others (almost). The decimals are called "pips", but whether they use two or four decimals vary with the currency pair involved, hence I need to somehow be open to both versions.
In a yen pair 110.00 would be a "hundred" and 110.50 would be a "fifty" (110.50 to 111.00 is 50 pips), while for say GBP 1.2500 would also be a "hundred" and 1.2550 would be a "fifty" (1.2500 to 1.2550 is also 50 pips).
The incoming variable is of type decimal. I do have access to a second decimal variable called UsePoint which would be 0.01 if the pair only has two decimals, but 0.0001 if it has four.
Does that clear up the issue?
Re
Dennis
 Edited by sgude1 Thursday, March 30, 2017 9:37 PM

Yes it does but I don't promise my math is going to be quite correct. Given the UsePoint variable you know whether you're dealing with 2 or 4 digits of precision. Use that to convert the value to "pips", then use normal math.
decimal ToPips ( decimal value, int precision ) { return value * (Math.Power(10, precision)); } var yen1 = ToPips(110.00, 2) => 110 * (10^2) = 11000; var yen2 = ToPips(110.50, 2) => 110.50 * (10^2) = 11050; var yenDifferenceInPips = yen1  yen2; var pound1 = ToPips(1.2500, 4) => 1.25 * (10^4) = 12500; var pound2 = ToPips(1.2550, 4) => 1.255 * (10^4) = 12550; var poundDifferenceInPips = pound1  pound2;
So basically this normalizes things. The more challenging aspect will be if you want to compare different "units". In this case you'll probably want to wrap this in an actual type that also tracks the "precision". Something to get you started (won't compile as is but should get you started).
public struct Pip { public Pip ( decimal value, int precision ) { Value = value; Precision = precision; } //Can create overloaded operators as needed public Pip Add ( Pip value2 ) { //If the precision matches then just add them if (Precision == value2.Precision) return new Pip(Value + value2.Value, Precision); //Pick the higher precision of the 2 values //and then "raise" the other value up to it ... } public int Precision { get; private set; } public decimal Value { get; private set; } }
So now you can work with values that that their "units" with them.
var yen = new Pip(110.00, 2); var pound = new Pip(1.2550, 4); //Result would be added value with precision of 4 var whateverThisIs = yen.Add(pound);
Of course the functionality you add will depend upon what behavior you need but a wrapper type makes it easy to track all this data. There are other ways to solve this problem as well but this is probably how I'd do it.
 Proposed as answer by Wendy ZangMicrosoft contingent staff, Moderator Friday, March 31, 2017 1:52 AM

