I have a property which has decimal datatype let's say "Interest" then I have another property of string type let's say "InterestString".
Properties
public decimal Interest { get; set; }
public string InterestString { get; set; }
I want to assign the value of Interest to InterestString so I did the following. For example lets assume Interest has a value of 4 (without decimal places):
InterestString = Interest.ToString();
If the conversion finished my InterestString becomes "4.000" but the value of my Interest is only 4 without .0000.
I want to retain the format even after conversion. How can I get rid of those insignificant decimal places?
If I do something like this
InterestString = Interest.ToString("N0");
It will give me InterestString="4";But what if I have Interest 4.5? This will give meInterestString = "5"` (rounded to ten).
If I do Interest.ToString("N2") that would give me still 2 insignificant decimal places. The behavior that I want is remove the insignficant decimal places.
Please help.
I don't think System.Decimal has a Normalize method, which is basically what you want. If you know how many decimal places you want at most you can use:
string x = Interest.ToString("0.######");
with as many # signs as you're interested in. Only significant digits will be filled in:
using System;
class Test
{
static void Main()
{
ShowInterest(4m); // 4
ShowInterest(4.0m); // 4
ShowInterest(4.00m); // 4
ShowInterest(4.1m); // 4.1
ShowInterest(4.10m); // 4.10
ShowInterest(4.12m); // 4.12
}
static void ShowInterest(decimal interest)
{
Console.WriteLine(interest.ToString("0.#####"));
}
}
Related
Let us say I am being given a 'string' formula from another source. Example:
NewCalculatedColumn = (Column1 * Column2)/Column3
I would like to apply this formula to create a calculated column for some data stored as double array (or DataTable - I have freedom here) in memory.
In this particular example, the array/dataset consist of 3 column and has thousands of rows. One option is to use DataColumn.Expressions, if the data is stored in a DataTable, as discussed here. However, this may not be the most efficient way. Any feedback would be very much appreciated. Many thanks!
DataTable is a much heavier data structure than a list of objects (or the more generic IEnumerable<T>), as it is indicated here.
So, if you are not forced into using a DataTable a list of objects that look like the following, can be used:
public ObjectType
{
public double Column1 { get; set; }
public double Column2 { get; set; }
public double Column3 { get; set; }
// avoid division by zero, adjust zero comparison threshold as needed
// also adjust returned value on zero
// using C# 6.0 specific syntax. If not available, use get { return } syntax
public double NewCalculatedColumn => Math.Abs(Column3) > 0.0001 ?
(Column1 * Column2)/Column3
: 0.0;
}
Even if you fetch data as DataTable, you can easily convert it to List<ObjectType> as indicated here.
[EDIT]
Based on comment, if expression can is dynamic, an external library can be used. E.g. NCalc:
public double NewCalculatedColumn
{
get
{
// you can provide a dynamic expression which contains col1, col2 and col3
//TODO: add exception handling
var e = new Expression($"(col1 * col2)/{col3}");
e.Parameters["col1"] = Column1;
e.Parameters["col2"] = Column2;
e.Parameters["col3"] = Column3;
return e.Evaluate();
}
}
Whenever I open my form (the one which stuff is being sent to) it crashes because a of a certain part. The part that is breaking it is Convert.ToInt32(txt_cost). Im looking to know how this should be sent to my other form without crashing the program
private void btn_HomepageSearch_Click(object sender, EventArgs e)
{
if (isValidData())
{
string destination = cbo_Destination.Text;
DateTime checkIn = date_FlightDate.Value;
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, Convert.ToInt32(txt_cost));
frm_HomePge.Show();
this.Hide();
}
}
Assuming you have an integer in your text box, i believe that should be
Convert.ToInt32(txt_cost.Text)
if it still crashes then the value of txt_cost can't be a valid int. try the below
var intValue = 0;
if (int.TryParse(txt_cost.Text, out intValue))
{
//do something with intValue
}
EDITED
( Code part from the comment of #Minimarshman ) :
case "ten":
price1 = 10;
break;
decimal total = price * price1;
txt_cost.Text = total.ToString("c");
So as you can see you're converting decimal to string and then assign that into a TextBox's Text property.
ALWAYS leave some margin for errors especially when you're doing software development. Meaning that you should NEVER TRUST that user will use your software as it was intended. Your usage of Convert.ToInt32(txt_cost) shows that you trust your/user data too much.
To deal with this you have to check every data that you're converting if it really is a valid data. c# has many built-in methods/functions that will validate that and the one you should use is decimal.TryParse which ensures that data is valid for the type conversion.
Another thing is that you're using special format for your ToString ("C") which indicates that it should put currency mark in the string. You have to remember to then get rid of this.
Code explanation :
decimal IfValueIsConvertibleItWillBeHeldHere = 0;
if(decimal.TryParse(txt_cost.Text.Split(' ')[0], out IfValueIsConvertibleItWillBeHeldHere)
{
frm_BookingPg frm_HomePge = new frm_BookingPg(
cbo_Destination.Text,
cbo_AmountOfPeople.Text,
(int)IfValueIsConvertibleItWillBeHeldHere // see the difference ?
);
frm_HomePge.Show();
this.Hide();
}
else
{
// show some message to the user that input was invalid
}
Remarks :
Doing so leaves you with chaotic code because converting from decimal to int using explicit type conversion will trim that value. For example decimal d = 0.5M; explicitly converted to int like int i = (int)d; will return 0 because it trims down the part after decimal mark ..
You should rewrite your frm_BookingPg to accept decimal type instead of int type so that the value will be accurate :
public frm_BookingPg(string destination, string amountOfPeople, decimal cost)
Instead of your actual :
public frm_BookingPg(string destination, string amountOfPeople, int cost)
Have you tried replacing
Convert.ToInt32(txt_cost)
with just an int32 literal value?
As follows:-
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, 1234);
does it still crash?
Is it possible to store this method with labels in class file?
Example:
aspx.cs
private void addSalat()
{
decimal sum= Convert.ToDecimal(Label6.Text);
decimal sum2= Convert.ToDecimal(Label17.Text);
decimal sum3= Convert.ToDecimal(Label54.Text);
decimal sum4= Convert.ToDecimal(Label66.Text);
decimal sum5= Convert.ToDecimal(Label78.Text);
decimal sum6= Convert.ToDecimal(Label90.Text);
decimal sum7= Convert.ToDecimal(Label102.Text);
decimal sum8= Convert.ToDecimal(Label114.Text);
decimal sum9= Convert.ToDecimal(Label126.Text);
decimal sum= sum+ sum2+
sum3+ sum4+ sum5+ sum6+ sum7+ sum8
+ sum9;
Label42.Text = sum.ToString();
}
//do calculations here and call this method in aspx.cs file, i dont't know how to put here labels if is possible:
public class Class1
{
public void Sum()
{
decimal sum= Convert.ToDecimal(Label6.Text);
decimal sum2= Convert.ToDecimal(Label17.Text);
decimal sum3= Convert.ToDecimal(Label54.Text);
decimal sum4= Convert.ToDecimal(Label66.Text);
decimal sum5= Convert.ToDecimal(Label78.Text);
decimal sum6= Convert.ToDecimal(Label90.Text);
decimal sum7= Convert.ToDecimal(Label102.Text);
decimal sum8= Convert.ToDecimal(Label114.Text);
decimal sum9= Convert.ToDecimal(Label126.Text);
decimal sum= sum+ sum2+
sum3+ sum4+ sum5+ sum6+ sum7+ sum8
+ sum9;
Label42.Text = sum.ToString();
}
}
You would have to do something like this:
private decimal Sum(decimal firstValue, params decimal[] moreValues)
{
decimal val = firstValue;
return val + moreValues.Sum(); // Note this is not recursion. It is calling the LINQ Sum() function.
}
And call it like this:
Sum(5.2); // returns 5.2
Sum(6, 10); // returns 16
Sum(1,2,3); // returns 6
Or something like this:
decimal sum = Sum(Convert.ToDecimal(Label6.Text),
Convert.ToDecimal(Label17.Text),
Convert.ToDecimal(Label54.Text)
// and so forth
);
I would just leave it in the code-behind of the page. Since you're basically just adding values there's not a lot to gain by splitting it into a different class. If you were doing more complex calculations that needed unit testing, etc. then I would consider splitting it out.
You could also make the code a little cleaner by using Linq to sum the values:
decimal sum = new [] {Label6, Label17, Label54, Label66, Label78, Label90, Label102, Label114, Label126}
.Sum(lbl => Convert.ToDecimal(lbl.Text));
I want to convert a string which contains 5 zeros ("00000") into a Int so it can be incremented.
Whenever I convert the string to an integer using Convert.ToInt32(), the value becomes 0.
How can I ensure that the integer stays at a fixed length once converted?
I want to be able to increment the value from "00000" to "00001" and so on so that the value appears with that many digits in a database instead of 0 or 1.
If you are going to down vote question, the least you could do is leave feedback on why you did it...
An integer is an integer. Nothing more.
So the int you have has value zero, there is no way to add any "length" metadata or similar.
I guess what you actually want is, that - at some point - there will be a string again. You want that string to represent your number, but with 5 characters and leading zeroes.
You can achieve that using:
string s = i.ToString("00000")
EDIT
You say you want the numbers to appear like that in your DB.
Ask yourself:
Does it really need to be like that in the DB or is it sufficient to format the numbers as soon as you read them from the database?
Depending on that, format them (as shown above), either when writing to or reading from the DB. Of course, the former case will require more storage space and you cannot really use SQL or similar to perform arithmetic operations!
An integer doesn't have a length, it's purely a numerical value. If you want to keep the length, you have to store the information about the length somewhere else.
You can wrap the value in an object that keeps the length in a property. Example:
public class FormattedInt {
private int _value, _length;
public FormattedInt(string source) {
_length = source.Length;
_value = Int32.Parse(source);
}
public void Increase() {
_value++;
}
public override string ToString() {
return _value.ToString(new String('0', _length));
}
}
Usage:
FormattedInt i = new FormattedInt("0004");
i.Increase();
string s = i.ToString(); // 0005
As olydis says above, an int is just a number. It doesn't specify the display format. I don't recommend storing it padded out with zeroes in a database either. It's an int, store it as an int.
For display purposes, in the app, a report, whatever, then pad out the zeroes.
string s = i.ToString("00000");
I have a field NumberValue1 declared like this
public double NumberValue1 { get; set; }
NumberValue1 has a datatype of Number in the
oracle database
I read in a value from an excel file which is
22.55
[[col8Value is an object type]]
I then did this.
NumberValue1 = col8Value == null ? 0 : Math.Round(Convert.ToDouble(col8Value),2)
When I inserted this into the database I got the number below stored
22.550000000000001
Why is it bringing the other ...00001.
I just want it to show the 22.55 which is the initial number I loaded
Thanks.
Try using
private int NumberStoreHundreths
public double NumberValue1
{
get
{
return ((double)NumberStoreHundreths)/100;
}
set
{
NumberStoreHundreths = (int)(value*100);
}
}
kind of old school, but should work
You don't need to change db column type, just use different datatype in app (hint - use decimal). (Answer by Koka Chernov)
This fixed my problem in 2015.