I have an 6digit integer, let's say "153060" that I'll like to split into
int a = 15 (first 2 digits),
int b = 30 (second 2 digits),
int c = 60 (third 2 digits),
The first thing that comes to mind is to convert the int to a string, split it using SubString (or a variation), and then convert back to an int.
This seems like a highly inefficient way to do it though. Can anyone recommend a better/faster way to tackle this?
Thanks!
Additional Info: the reason for splitting the int is because the 6-digit integer represents HHMMSS, and I'd like to use it to create a new DateTime instance:
DateTime myDateTime = new DateTime (Year, Month, Day, a , b, c);
However, the user-field can only accept integers.
int y = number / 10000;
int m = (number - y*10000) / 100;
in d = number % 100;
If your end goal is a DateTime, you could use TimeSpan.ParseExact to extract a TimeSpan from the string, then add it to a DateTime:
TimeSpan time = TimeSpan.ParseExact(time, "hhmmss", CultureInfo.InvariantCulture);
DateTime myDateTime = new DateTime(2011, 11, 2);
myDateTime = myDateTime.Add(time);
(Assumes >= .NET 4)
How about something like this?
int i = 153060;
int a = i / 10000;
int b = (i - (a * 10000)) / 100;
int c = (i - ((a * 10000) + (b * 100)));
You can do that without converting to string with:
int a = 153060 / 10000;
int b = (153060 / 100) % 100;
int c = 153060 % 100;
I am not sure about how efficient that is compared to converting to string. I think this is only 4 operations. So it might be faster.
Related
I have the following code to divide an amount by a number and allocate the result as an amount that needs to be paid per month.
objData.month_per_amount = (Convert.ToDecimal(txtAmount.Value) / Convert.ToInt32(txtMonths.Value));
In a scenario example if I divide 13 by 3 and round off the result to 2 decimal places I get 4.33 for each month. But when I multiply 4.33 by 3 I am getting 12.99, which is not equivalent to 13. There is a discrepancy of 0.01. In this scenario how can I allocate like below:
month 1: 4.33
month 2: 4.33
month 3: 4.34
Hope I made it clear, the preferred code should only be executed if there is such a discrepancy, for example if 14 is to be divided by 2, we get 7 for each month and 7+7=14, so exactly the same figure we are getting here.
In accounting you'd often use something called 'reducing balance' for this. The idea is that you calculate the month's total, deduct it from the overall total and reduce the number of months. So something like:
decimal balance = 13m;
int months = 3;
int monthsRemaining = 3;
for (var i = 0; i < months; i++)
{
decimal thisMonth = Math.Round(balance / monthsRemaining, 2);
balance -= thisMonth;
monthsRemaining -= 1;
Console.WriteLine("Month {0}: {1}", i + 1, thisMonth);
}
This will result in 4.33, 4.34, 4.33.
The benefit of this method is that the rounding errors are distributed fairly evenly throughout the period rather than all in one month. For example, 100 over 24 months using that method would result in 23 payments of 4.17 and 1 of 4.09 whereas reducing balance would be 4.16 or 4.17 each month.
You do not have to check the remainder. A more efficient C# code (in terms of the required computation) would be like the following.
double amount = 13;
int months = 3;
int precision = 2;
double[] amountForEachMonth = new double[months];
double temp = Math.Round(amount / months, precision);
for (int i = 0 ; i < months - 1 ; i++)
amountForEachMonth[i] = temp;
amountForEachMonth[months - 1] = amount - (temp * (months - 1)) ;
You don't need to make it a special case when there is a discrepancy, you can simply always calculate the payment of the last month as what's left to pay to reach the total amount. If there is no discrepancy then it will be the same value anyway. Example:
int months = Convert.ToInt32(txtMonths.Value);
decimal amount = Convert.ToDecimal(txtAmount.Value);
month_per_amount = Decimal.Round(amount / months, 2);
decimal last_month = amount - (months - 1) * month_per_amount;
for (int month = 1; month <= months; month++) {
decimal monthly = month < months ? month_per_amount : last_month;
Console.WriteLine("Month {0}: {1}", month, monthly);
}
if " amount % month == 0 " , no discrepancy occures. otherwise, the last item should be a little more than others .
(The code here may have some syntax issues, I wanted to show you the algorithm.)
decimal amount = Convert.ToDecimal(txtAmount.Value);
int month = Convert.ToInt32(txtMonths.Value);
int n = 3;
decimal amounts[3];//n = 3
for (int i = 0 ; i < n-1 ; i++)
amounts[i] = amount / month;
if ( amount % month != 0 ) {
amounts[n-1] = amount - ( amount / month * (n-1) ) ;
else
amounts[n-1] = amount / month ;
I would like to round my answer 1 decimal place. for example: 6.7, 7.3, etc.
But when I use Math.round, the answer always come up with no decimal places. For example: 6, 7
Here is the code that I used:
int [] nbOfNumber = new int[ratingListBox.Items.Count];
int sumInt = 0;
double averagesDoubles;
for (int g = 0; g < nbOfNumber.Length; g++)
{
nbOfNumber[g] = int.Parse(ratingListBox.Items[g].Text);
}
for (int h = 0; h < nbOfNumber.Length; h++)
{
sumInt += nbOfNumber[h];
}
averagesDoubles = (sumInt / ratingListBox.Items.Count);
averagesDoubles = Math.Round(averagesDoubles, 2);
averageRatingTextBox.Text = averagesDoubles.ToString();
You're dividing by an int, it wil give an int as result. (which makes 13 / 7 = 1)
Try casting it to a floating point first:
averagesDoubles = (sumInt / (double)ratingListBox.Items.Count);
The averagesDoubles = Math.Round(averagesDoubles, 2); is reponsible for rounding the double value. It will round, 5.976 to 5.98, but this doesn't affect the presentation of the value.
The ToString() is responsible for the presentation of decimals.
Try :
averagesDoubles.ToString("0.0");
Do verify that averagesDoubles is either double or decimal as per the definition of Math.Round and combine these two lines :
averagesDoubles = (sumInt / ratingListBox.Items.Count);
averagesDoubles = Math.Round(averagesDoubles, 2);
TO :
averagesDoubles = Math.Round((sumInt / ratingListBox.Items.Count),2);
2 in the above case represents the number of decimals you want to round upto. Check the link above for more reference.
int division will always ignore fraction
(sumInt / ratingListBox.Items.Count);
here sumint is int and ratingListBox.Items.Count is also int , so divison never results in fraction
to get the value in fraction , you need to datatype like float and type cast the sumInt and count to float and double and then use divison
var val= Math.Ceiling(100.10m);
result 101
I am trying make a clock. The hour is a string. I want to put that hour into a char array so i can separate the hour into one or two indexes. That way i can use a case on the individual indexes to ultimately bind it to a grid and draw a line for the digital time..
So, the hour is converted to an array. But i want to take the first index 0 and store it into a string or int so i can pass it into a function where i can use a case on it. if i leave it as a char and convert it to an int i get a number like 50 which is no good.
So, when i try to assign the first index of the array to a string it wont let me convert from array to string.
hr1 = hours[0];
What is my best option of seperating the hour into separate indexes and then converting it over to the proper int? Also, the time is on 24 hour and i would like it to be 12 hour.
private void _timer_Elapsed(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
//DigitalTime = now.ToString("hh:mm:ss tt");
//DigitalTime = now.ToString();
//DigitalTime = DateTime.Now.Hour.ToString();
SecondAngle = now.Second * 6;
MinuteAngle = now.Minute * 6;
HourAngle = (now.Hour * 30) + (now.Minute * 0.5);
string hrs, hr1, hr2;
char[] hours = new char[15];
hrs = DateTime.Now.Hour.ToString("hh:mm:ss tt");
hours = hrs.ToCharArray();
if (hours.Length > 1)
{
hr1 = hours[0]; // error -
hr2 = hours[1];
// SetHourDigit1(Convert.ToInt32(hr1));
}
else
{
// hr1 = '0';
hr2 = hours[0];
}
}
public void SetHourDigit1(int num)
{
switch (num)
{
case 0:
MessageBox.Show("num" + num);
break;
case 1:
MessageBox.Show("num" + num);
break;
case 2:
break;
}
}
I would avoid messing with strings and char arrays altogether. Use arithmetic instead:
int hour = DateTime.Now.Hour;
int leastSignificantDigit = hour % 10;
int mostSignificantDigit = hour / 10;
// Use one of these as input for your switch statement.
% is the modulo operator; the remainder of a division by 10 in this case.
Edit: I noticed you want to have a 12-hour clock. You can add some additional computation for this. Replacement for the first line of code:
int hour = DateTime.Now.Hour % 12;
if (hour == 0) hour = 12;
if (hours.Length > 1)
{
hr1 = hours[0].ToString(); // no error -
hr2 = hours[1].ToString();
// SetHourDigit1(Convert.ToInt32(hr1));
}
but if you want to get parts of time use this:
dateparts = datestring.splite(':');
string hour = dateparts[0];
string minute = dateparts[1];
string s = dateparts[2];
now you have hour,minute,second and t.
because of you can trust the parts use int.parse to convert them to int.
int nhour = int.parse(hour);
int nminute = int.parse(minute);
int nsecond = int.parse(s);
for 24 hours
hrs = DateTime.Now.Hour.ToString("HH:mm:ss");
This is a usefull link for u:
DateTime.ToString() Pattern
Use the modulo (%) operator to convert the 24 hour value to 12 hours, and also to get the second digit of the two digit number. There is no reason to format it as a string and then convert it back to numbers.
private void _timer_Elapsed(object sender, EventArgs e) {
DateTime now = DateTime.Now;
int hour12 = now.Hour % 12;
SecondAngle = now.Second * 6;
MinuteAngle = now.Minute * 6;
HourAngle = (hour12 * 30) + (now.Minute * 0.5);
SetHourDigit1(hour12 / 10);
SetHourDigit2(hour12 % 10);
}
pls, I HAVE A NUMBER say 9 and i want to find how to create a program to check if a number b is maybe 21(ie 9+12) or 33(ie 9 + 24) or 45(9 + 36) and so on. Can i get it in C# or SQL
With the clarification, it looks like you want to find whether there is an integer x for which (in math terms, not code)
b = 9 + 12x
is true; so you want to know whether b-9 is some multiple of 12; which is easy:
bool isMatch = ((b - 9) % 12) == 0;
and if you want to know which x:
int x = (b - 9) / 12;
It's not entirely clear from your question, but I think you're looking for the modulo operator. 21 % 12 = 9, 33 % 12 = 9, 45 % 12 = 9.
In C# and SQL this is just %, and it is used like an arithmetic operator (+, -, etc)
I think you've got three variables and than the solution will be like this:
var a = 9;
var b = 12;
var c = 21;
var isInRange = IsInRange(c, a, b);
private bool IsInRange(int input, int offset, int multiple){
return ((input - offset) % multiple) == 0;
}
Subtract your original number (in this case 9) from the number B, and then see if B % 12 is different from zero.
I want to get a six digit number by user and spit it into 3 parts as(day, month, year)
Example:
int date=111213;
day =11;
month =12;
year =13;
I think I have to convert it into string then by using substring() I can do this.
Any easy Idea ??
How about:
// Assuming a more sensible format, where the logically most significant part
// is the most significant part of the number too. That would allow sorting by
// integer value to be equivalent to sorting chronologically.
int day = date % 100;
int month = (date / 100) % 100;
int year = date / 10000;
// Assuming the format from the question (not sensible IMO)
int year = date % 100;
int month = (date / 100) % 100;
int day = date / 10000;
(Do you have to store your data like this to start with? Ick.)
Storing a date as an integer like this isn't ideal, but if you must do it -- and you're sure that the number will always use the specified format -- then you can easily extract the day, month and year:
int day = date / 10000;
int month = (date / 100) % 100;
int year = date % 100;
You can do this with modular arithmetic:
int day = date / 10000;
int month = (date / 100) % 100;
int year = date % 100;
Here is the solution in Java with no optimization:
final int value = 111213;
int day;
int month;
int year;
day = value / 10000;
month = (value - (day * 10000)) / 100;
year = (value - (day * 10000)) - month * 100;