Assume i want to create an alias of a type in C# using a hypothetical syntax:
Currency = float;
Then i go away and create a few thousand files that use Currency type.
Then i realize that i prefer to use FCL types:
Currency = System.Single;
Excellent, all code still works.
...months later...
Wait, i'm getting some strange rounding errors. Oh that's why, System.Single only has 7 digits of precision. Lets up that to 15 digits:
Currency = System.Double;
...years later...
Ohhhh, floating point isn't exact; multiplying $0.0011/unit * 217,384 units exposes some limitations of using floating point. And accountants are sticklers against "accounting irregularities". No problem:
Currency = System.Decimal;
...years later...
International applications? Currency codes. Hmmmm. Thank you CodeProject:
Currency = Money;
...later...
Ooo, patterns and practices. Let's obfuscate some of that code:
Currency = ICurrency;
And during all this nonsense code didn't break.
i know C# doesn't support this level of encapsulation and resilency with the syntax i made up.
But can anyone suggest a syntax that can simulate what people have been trying to accomplish (including myself)?
Create a class called Currency and implement (or delegate) the appropriate operators, then just change the class used to store the data internally when desired.
You can use using like so: using Currency = System.Single;, but you must do it in every single file. But still easier to change, than searching for single in whole application.
Related
I know that the consensus is "money = decimal". I understand all the technical fine point of the argument, and agree with that.
Where I still have issue is that it's seems to assume that all finance applications are simple ledger...
When you start to play with ratio, interpolation (cubic spline for example) or if you move to some Stochastic model, differentiate, integral... it seems that the decimal become meaningless.
So my question is where is the border (mathematical complexity?) when using decimal become more a burden that an advantage?
EDIT: most of complex financial product use statistical model in order to be priced. In the end the price is a $$, and as Flydog57 point out, most (if not all) mathematical library used double as input/output.
So unless I redeveloped all these mathematical functions (that has been develops by people way smarter than me) I need to constantly cast decimal to double and conversely. That's where the problem is.
Is it useful to use decimal "because it's money" if in the end I constantly need to cast it in double to be able to create a price?
That where the argument saying (money = decimal) may be a simplistic view of a real world problem. I know the question seems to be duplicate but all the other answer out there don't deal with this specify case where a price (money) is actually created from a statistical model
I encountered a scenario where i have to send an array of integers as parameter from specflow feature file. I could have used tables which i don't want to do as i have send as row[] or col[]. If i pass parameter as a string
eg: Given set the value as '470,471,472,472'
and receive it and do split in step definition file. How different is StepArgumentTransformation from the above scenario? Is any other benefit in using step argument transformation. I understand we can convert XML,Date or any object. Why do we have to use stepargumenttransformation???
I hope I understood the question correctly.
Specflow supports some automatic transformation out of the box, so things like converting to Date, Double, int etc etc, and it does these by default as there is no ambiguity about them. You can easily convert a string to a double or a Date as you know the locale being used.
Why isn't converting to arrays supported? I suppose it could be, but there is some ambiguity. What should the list separator be? a comma? What about locales that use that as a separator between the whole and fractional part of a number?
So providing a default implementation of something which converted a list to int[] or IEnumerable<int> could be possible, but its just likely to get some people asking why it doesn't work for them when they have used ☃ as a list separator.
It's better to leave the things with ambiguity to individuals to implement, rather than guess at the best implementation.
The StepArgumentTransformation you want is very simple to write and could be included in an external step assembly if you wanted to share it amongst many projects.
So to answer your many questions:
It's not really any different, it just encapsulates it in a single place, which is good practise, which is a benefit.
Yes you can convert any object.
You don't have to use StepArgumentTransformation, many people don't, but IMHO they make your life much easier
I found very confusing when sorting a text file. Different algorithm/application produces different result, for example, on comparing two string str1=";P" and str2="-_-"
Just for your reference here gave the ASCII for each char in those string:
char(';') = 59; char('P') = 80;
char('-') = 45; char('_') = 95;
So I've tried different methods to determine which string is bigger, here is my result:
In Microsoft Office Excel Sorting command:
";P" < "-_-"
C++ std::string::compare(string &str2), i.e. str1.compare(str2)
";P" > "-_-"
C# string.CompareTo(), i.e. str1.CompareTo(str2)
";P" < "-_-"
C# string.CompareOrdinal(), i.e. CompareOrdinal(w1, w2)
";P" > "-_-"
As shown, the result varied! Actually my intuitive result should equal to Method 2 and 4, since the ASCII(';') = 59 which is larger than ASCII('-') = 45 .
So I have no idea why Excel and C# string.CompareTo() gives a opposite answer. Noted that in C# the second comparison function named string.CompareOrdinal(). Does this imply that the default C# string.CompareTo() function is not "Ordinal" ?
Could anyone explain this inconsistency?
And could anyone explain in CultureInfo = {en-US}, why it tells ;P > -_- ? what's the underlying motivation or principle? And I have ever heard about different double multiplication in different cultureInfo. It's rather a cultural shock..!
?
std::string::compare: "the result of a character comparison depends only on its character code". It's simply ordinal.
String.CompareTo: "performs a word (case-sensitive and culture-sensitive) comparison using the current culture". So,this not ordinal, since typical users don't expect things to be sorted like that.
String::CompareOrdinal: Per the name, "performs a case-sensitive comparison using ordinal sort rules".
EDIT: CompareOptions has a hint: "For example, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list."
Excel 2003 (and earlier) does a sort ignoring hyphens and apostrophes, so your sort really compares ; to _, which gives the result that you have. Here's a Microsoft Support link about it. Pretty sparse, but enough to get the point across.
I'm trying to build a "simple" web app that calculates either a male or females body fat % based on the U.S. Navy's circumference formula. I have the majority of the app completed at this point. However, I cannot figure out why the way I've setup the formula below won't work. Two of the values are underlined in red in my .cs file.
My Formula:
TBBodyFat.Text = Convert.ToString(495 / (1.0324-.19077(Math.Log(Convert.ToDouble(TBWaist.Text)-Convert.ToDouble(TBNeck.Text)))+.15456(Math.Log(Convert.ToDouble(TBHeight.Text)))));
Original Example:
%Fat=495/(1.0324-.19077(log(abdomen-neck))+.15456(log(height)))-450
Pop-Up for the two underlined values (.19077 and .15456):
struct System.Double
Represents a double-precision floating-point number.
Error:
Method name expected
TBBodyFat.Text = Convert.ToString(495 / (1.0324-.19077*
(Math.Log(Convert.ToDouble(TBWaist.Text)-Convert.ToDouble(TBNeck.Text)))+.15456*
(Math.Log(Convert.ToDouble(TBHeight.Text)))));
C# (not any programming language I've yet encountered) does not take adjacency of numbers to mean multiplication!
Well you need to use "*" for multiplication. Plus I'm not sure whether C# allows ".123" style numeric literals without leading 0.
Try:
TBBodyFat.Text =
Convert.ToString(495/
(1.0324-0.19077*(Math.Log(Convert.ToDouble(TBWaist.Text)-Convert.ToDouble(TBNeck.Text)))+0.15456*(Math.Log(Convert.ToDouble(TBHeight.Text)))));
Put * while multiplying like .8*(b-200) .If you will put directly .8(b-200) it will show error that method name expected.
What is best practice for the scenario listed below?
We have an application which we would like to support multiple currencies. The software will respect the users locale and regional settings to dictate the correct number format, i.e. $10,000.00 or 10.000,00₴ etc.
We would however like to be able to format different numbers based upon a currency ID (perhaps the three letter ISO4217 code). Our idea is to store a table in the database with each currency and then request from the user to select the currency symbol which will be used. The program will then format all numbers based upon the locale/region setting but will use the currency symbol as defined in our program.
So, given the following values and currencies
10000 AUD
5989.34 USD
450 EUR
the program would output
$10,000.00
$5,989.34
€450.00
or with a regional setting that formated numbers as #####,##$ the result would be;
10000,00$
5989,34$
450,00€
Respecting locale/region number formatting but displaying different currencies, what is best practice for this?
I hope this makes sense.
Technology used is c# .NET 2.0.
I think this Q is an excellent and clear answer as to WHAT you should be doing
SO - Proper currency format when not displaying the native currency of a culture
And this Q has a good answer of HOW to do this in C#
SO - Currency formatting
It sounds like you have a handle on the best practices for formatting data. If I were you I would worry less about what is technically the standard but focus more on what it is your users are accustomed to.
If you are operating in markets where users are fairly savvy about different currencies it is a very different thing than having more monocultural users. Depending on the case, you will need to design your interface in a different way.
Moreover, if your requirement is to display any currency to any locale, the ISO4217 standard is your best bet. It is what is shown at currency exchange shops across the world, on currency exchanges, invoices, etc. Otherwise, displaying currency symbols could be rather confusing to some users and the symbol by itself does not indicate what currency the amount actually is.
I would also reference the following SO questions. Not all of them directly relate to your problem, but they have very good meta discussions about the issues involved in supporting multiple currencies.
How do I round up currency values in Java
Representing Monetary Values in Java
What to do with Java BigDecimal performance?
Rather than storing just the currency symbol, you could store the culture string for each currency code, so AUD --> en-AU
CultureInfo ci = new CultureInfo("en-AU");
currencyValue.ToString( "c", ci );
I'm not sure how much flexibility there is in formatting available.
Not sure if this helps:
Formatting Numeric Data for a Specific Culture
You could store the money value as a decimal, then append the currency symbol on the UI.
Fowler discusses the Money pattern in Patterns of Enterprise Application Architecture here: http://www.martinfowler.com/eaaCatalog/money.html
I faced a similar situation. I found a way, dont know how useful it will be for you. But it solved my problems. I set a session string for each place like Session["cur"]="0.000" or "0.00" for each login authentication. And where ever currency comes in the system I used .ToString[Session["cur"].ToString()] to the model variables. It did the trick for me . Hope it helps you too .