c# Math function not calulating - c#

I have a simple math function
private int Doyle(LogArguments args)
{
return Convert.ToInt32(Math.Round(Math.Pow((args.Diameter - 4) , 2.0) * (args.Length / 16),0));
}
that should always return an int > 0 but my problem is if args.Length <= 16 it args.Length/16 = 0.
I have tried:
decimal d = args.length/16
and double d = args.length/16;
which both turn out to 0 when Length <16

If args.length is an int you are doing integer division regardless of what the type of the output variable is. To force decimal division the simplest way is to specify a decimal literal in the denominator:
decimal d = args.length / 16M;
Or for a double use a floating-point literal:
double d = args.length / 16.0;

double d = args.length/16;
which both turn out to 0 when Length <16
That is because args.Length and 16 are both integers. You get integer division (result 0), which is then cast to a double. Instead, try
double d = args.length/16.0;

If you are trying to multiply by a float value such as this:
5 / 16 = 0.3125
Then you should turn (args.Length / 16) into (args.Length / 16f).
This will force the division to be does as a floating point, and keep any remainder. Without the f added, it will do it as an integer division which truncates the remainder, so any value less than 16 will be less than 1 and get reduced to 0.

Related

Show formatted decimal rounding to specific amount of digits [duplicate]

If I have a double (234.004223), etc., I would like to round this to x significant digits in C#.
So far I can only find ways to round to x decimal places, but this simply removes the precision if there are any 0s in the number.
For example, 0.086 to one decimal place becomes 0.1, but I would like it to stay at 0.08.
The framework doesn't have a built-in function to round (or truncate, as in your example) to a number of significant digits. One way you can do this, though, is to scale your number so that your first significant digit is right after the decimal point, round (or truncate), then scale back. The following code should do the trick:
static double RoundToSignificantDigits(this double d, int digits){
if(d == 0)
return 0;
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return scale * Math.Round(d / scale, digits);
}
If, as in your example, you really want to truncate, then you want:
static double TruncateToSignificantDigits(this double d, int digits){
if(d == 0)
return 0;
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1 - digits);
return scale * Math.Truncate(d / scale);
}
I've been using pDaddy's sigfig function for a few months and found a bug in it. You cannot take the Log of a negative number, so if d is negative the results is NaN.
The following corrects the bug:
public static double SetSigFigs(double d, int digits)
{
if(d == 0)
return 0;
decimal scale = (decimal)Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return (double) (scale * Math.Round((decimal)d / scale, digits));
}
It sounds to me like you don't want to round to x decimal places at all - you want to round to x significant digits. So in your example, you want to round 0.086 to one significant digit, not one decimal place.
Now, using a double and rounding to a number of significant digits is problematic to start with, due to the way doubles are stored. For instance, you could round 0.12 to something close to 0.1, but 0.1 isn't exactly representable as a double. Are you sure you shouldn't actually be using a decimal? Alternatively, is this actually for display purposes? If it's for display purposes, I suspect you should actually convert the double directly to a string with the relevant number of significant digits.
If you can answer those points, I can try to come up with some appropriate code. Awful as it sounds, converting to a number of significant digits as a string by converting the number to a "full" string and then finding the first significant digit (and then taking appropriate rounding action after that) may well be the best way to go.
If it is for display purposes (as you state in the comment to Jon Skeet's answer), you should use Gn format specifier. Where n is the number of significant digits - exactly what you are after.
Here is the the example of usage if you want 3 significant digits (printed output is in the comment of each line):
Console.WriteLine(1.2345e-10.ToString("G3"));//1.23E-10
Console.WriteLine(1.2345e-5.ToString("G3")); //1.23E-05
Console.WriteLine(1.2345e-4.ToString("G3")); //0.000123
Console.WriteLine(1.2345e-3.ToString("G3")); //0.00123
Console.WriteLine(1.2345e-2.ToString("G3")); //0.0123
Console.WriteLine(1.2345e-1.ToString("G3")); //0.123
Console.WriteLine(1.2345e2.ToString("G3")); //123
Console.WriteLine(1.2345e3.ToString("G3")); //1.23E+03
Console.WriteLine(1.2345e4.ToString("G3")); //1.23E+04
Console.WriteLine(1.2345e5.ToString("G3")); //1.23E+05
Console.WriteLine(1.2345e10.ToString("G3")); //1.23E+10
I found two bugs in the methods of P Daddy and Eric. This solves for example the precision error that was presented by Andrew Hancox in this Q&A. There was also a problem with round directions. 1050 with two significant figures isn't 1000.0, it's 1100.0. The rounding was fixed with MidpointRounding.AwayFromZero.
static void Main(string[] args) {
double x = RoundToSignificantDigits(1050, 2); // Old = 1000.0, New = 1100.0
double y = RoundToSignificantDigits(5084611353.0, 4); // Old = 5084999999.999999, New = 5085000000.0
double z = RoundToSignificantDigits(50.846, 4); // Old = 50.849999999999994, New = 50.85
}
static double RoundToSignificantDigits(double d, int digits) {
if (d == 0.0) {
return 0.0;
}
else {
double leftSideNumbers = Math.Floor(Math.Log10(Math.Abs(d))) + 1;
double scale = Math.Pow(10, leftSideNumbers);
double result = scale * Math.Round(d / scale, digits, MidpointRounding.AwayFromZero);
// Clean possible precision error.
if ((int)leftSideNumbers >= digits) {
return Math.Round(result, 0, MidpointRounding.AwayFromZero);
}
else {
return Math.Round(result, digits - (int)leftSideNumbers, MidpointRounding.AwayFromZero);
}
}
}
As Jon Skeet mentions: better handle this in the textual domain. As a rule: for display purposes, don't try to round / change your floating point values, it never quite works 100%. Display is a secondary concern and you should handle any special formatting requirements like these working with strings.
My solution below I implemented several years ago and has proven very reliable. It has been thoroughly tested and it performs quite well also. About 5 times longer in execution time than P Daddy / Eric's solution.
Examples of input + output given below in code.
using System;
using System.Text;
namespace KZ.SigDig
{
public static class SignificantDigits
{
public static string DecimalSeparator;
static SignificantDigits()
{
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
}
/// <summary>
/// Format a double to a given number of significant digits.
/// </summary>
/// <example>
/// 0.086 -> "0.09" (digits = 1)
/// 0.00030908 -> "0.00031" (digits = 2)
/// 1239451.0 -> "1240000" (digits = 3)
/// 5084611353.0 -> "5085000000" (digits = 4)
/// 0.00000000000000000846113537656557 -> "0.00000000000000000846114" (digits = 6)
/// 50.8437 -> "50.84" (digits = 4)
/// 50.846 -> "50.85" (digits = 4)
/// 990.0 -> "1000" (digits = 1)
/// -5488.0 -> "-5000" (digits = 1)
/// -990.0 -> "-1000" (digits = 1)
/// 0.0000789 -> "0.000079" (digits = 2)
/// </example>
public static string Format(double number, int digits, bool showTrailingZeros = true, bool alwaysShowDecimalSeparator = false)
{
if (Double.IsNaN(number) ||
Double.IsInfinity(number))
{
return number.ToString();
}
string sSign = "";
string sBefore = "0"; // Before the decimal separator
string sAfter = ""; // After the decimal separator
if (number != 0d)
{
if (digits < 1)
{
throw new ArgumentException("The digits parameter must be greater than zero.");
}
if (number < 0d)
{
sSign = "-";
number = Math.Abs(number);
}
// Use scientific formatting as an intermediate step
string sFormatString = "{0:" + new String('#', digits) + "E0}";
string sScientific = String.Format(sFormatString, number);
string sSignificand = sScientific.Substring(0, digits);
int exponent = Int32.Parse(sScientific.Substring(digits + 1));
// (the significand now already contains the requested number of digits with no decimal separator in it)
StringBuilder sFractionalBreakup = new StringBuilder(sSignificand);
if (!showTrailingZeros)
{
while (sFractionalBreakup[sFractionalBreakup.Length - 1] == '0')
{
sFractionalBreakup.Length--;
exponent++;
}
}
// Place decimal separator (insert zeros if necessary)
int separatorPosition = 0;
if ((sFractionalBreakup.Length + exponent) < 1)
{
sFractionalBreakup.Insert(0, "0", 1 - sFractionalBreakup.Length - exponent);
separatorPosition = 1;
}
else if (exponent > 0)
{
sFractionalBreakup.Append('0', exponent);
separatorPosition = sFractionalBreakup.Length;
}
else
{
separatorPosition = sFractionalBreakup.Length + exponent;
}
sBefore = sFractionalBreakup.ToString();
if (separatorPosition < sBefore.Length)
{
sAfter = sBefore.Substring(separatorPosition);
sBefore = sBefore.Remove(separatorPosition);
}
}
string sReturnValue = sSign + sBefore;
if (sAfter == "")
{
if (alwaysShowDecimalSeparator)
{
sReturnValue += DecimalSeparator + "0";
}
}
else
{
sReturnValue += DecimalSeparator + sAfter;
}
return sReturnValue;
}
}
}
Math.Round() on doubles is flawed (see Notes to Callers in its documentation). The later step of multiplying the rounded number back up by its decimal exponent will introduce further floating point errors in the trailing digits. Using another Round() as #Rowanto does won't reliably help and suffers from other problems. However if you're willing to go via decimal then Math.Round() is reliable, as is multiplying and dividing by powers of 10:
static ClassName()
{
powersOf10 = new decimal[28 + 1 + 28];
powersOf10[28] = 1;
decimal pup = 1, pdown = 1;
for (int i = 1; i < 29; i++) {
pup *= 10;
powersOf10[i + 28] = pup;
pdown /= 10;
powersOf10[28 - i] = pdown;
}
}
/// <summary>Powers of 10 indexed by power+28. These are all the powers
/// of 10 that can be represented using decimal.</summary>
static decimal[] powersOf10;
static double RoundToSignificantDigits(double v, int digits)
{
if (v == 0.0 || Double.IsNaN(v) || Double.IsInfinity(v)) {
return v;
} else {
int decimal_exponent = (int)Math.Floor(Math.Log10(Math.Abs(v))) + 1;
if (decimal_exponent < -28 + digits || decimal_exponent > 28 - digits) {
// Decimals won't help outside their range of representation.
// Insert flawed Double solutions here if you like.
return v;
} else {
decimal d = (decimal)v;
decimal scale = powersOf10[decimal_exponent + 28];
return (double)(scale * Math.Round(d / scale, digits, MidpointRounding.AwayFromZero));
}
}
}
I agree with the spirit of Jon's assessment:
Awful as it sounds, converting to a number of significant digits as a string by converting the number to a "full" string and then finding the first significant digit (and then taking appropriate rounding action after that) may well be the best way to go.
I needed significant-digit rounding for approximate and non-performance-critical computational purposes, and the format-parse round-trip through "G" format is good enough:
public static double RoundToSignificantDigits(this double value, int numberOfSignificantDigits)
{
return double.Parse(value.ToString("G" + numberOfSignificantDigits));
}
This question is similiar to the one you're asking:
Formatting numbers with significant figures in C#
Thus you could do the following:
double Input2 = 234.004223;
string Result2 = Math.Floor(Input2) + Convert.ToDouble(String.Format("{0:G1}", Input2 - Math.Floor(Input2))).ToString("R6");
Rounded to 1 significant digit.
Let inputNumber be input that needs to be converted with significantDigitsRequired after decimal point, then significantDigitsResult is the answer to the following pseudo code.
integerPortion = Math.truncate(**inputNumber**)
decimalPortion = myNumber-IntegerPortion
if( decimalPortion <> 0 )
{
significantDigitsStartFrom = Math.Ceil(-log10(decimalPortion))
scaleRequiredForTruncation= Math.Pow(10,significantDigitsStartFrom-1+**significantDigitsRequired**)
**siginficantDigitsResult** = integerPortion + ( Math.Truncate (decimalPortion*scaleRequiredForTruncation))/scaleRequiredForTruncation
}
else
{
**siginficantDigitsResult** = integerPortion
}
Tested on .NET 6.0
In my opinion, the rounded results are inconsistent due to the defects of the framework and the error of the floating point. Therefore, be careful about use.
decimal.Parse(doubleValue.ToString("E"), NumberStyles.Float);
example:
using System.Diagnostics;
using System.Globalization;
List<double> doubleList = new();
doubleList.Add( 0.012345);
doubleList.Add( 0.12345 );
doubleList.Add( 1.2345 );
doubleList.Add( 12.345 );
doubleList.Add( 123.45 );
doubleList.Add( 1234.5 );
doubleList.Add(12345 );
doubleList.Add(10 );
doubleList.Add( 0 );
doubleList.Add( 1 );
doubleList.Add(-1 );
doubleList.Add( 0.1);
Debug.WriteLine("");
foreach (var item in doubleList)
{
Debug.WriteLine(decimal.Parse(item.ToString("E2"), NumberStyles.Float));
// 0.0123
// 0.123
// 1.23
// 12.3
// 123
// 1230
// 12300
// 10.0
// 0.00
// 1.00
// -1.00
// 0.100
}
Debug.WriteLine("");
foreach (var item in doubleList)
{
Debug.WriteLine(decimal.Parse(item.ToString("E3"), NumberStyles.Float));
// 0.01235
// 0.1235
// 1.234
// 12.35
// 123.5
// 1234
// 12340
// 10.00
// 0.000
// 1.000
// -1.000
// 0.1000
}
As pointed out by #Oliver Bock is that Math.Round() on doubles is flawed (see Notes to Callers in its documentation). The later step of multiplying the rounded number back up by its decimal exponent will introduce further floating point errors in the trailing digits. Generally, any multiplication by or division by a power of ten gives a non-exact result, since floating-point is typically represented in binary, not in decimal.
Using the following function will avoid floating point errors in the trailing digits:
static double RoundToSignificantDigits(double d, int digits)
{
if (d == 0.0 || Double.IsNaN(d) || Double.IsInfinity(d))
{
return d;
}
// Compute shift of the decimal point.
int shift = digits - 1 - (int)Math.Floor(Math.Log10(Math.Abs(d)));
// Return if rounding to the same or higher precision.
int decimalPlaces = 0;
for (long pow = 1; Math.Floor(d * pow) != (d * pow); pow *= 10) decimalPlaces++;
if (shift >= decimalPlaces)
return d;
// Round to sf-1 fractional digits of normalized mantissa x.dddd
double scale = Math.Pow(10, Math.Abs(shift));
return shift > 0 ?
Math.Round(d * scale, MidpointRounding.AwayFromZero) / scale :
Math.Round(d / scale, MidpointRounding.AwayFromZero) * scale;
}
However if you're willing to go via decimal then Math.Round() is reliable, as is multiplying and dividing by powers of 10:
static double RoundToSignificantDigits(double d, int digits)
{
if (d == 0.0 || Double.IsNaN(d) || Double.IsInfinity(d))
{
return d;
}
decimal scale = (decimal)Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return (double)(scale * Math.Round((decimal)d / scale, digits, MidpointRounding.AwayFromZero));
}
Console.WriteLine("{0:G17}", RoundToSignificantDigits(5.015 * 100, 15)); // 501.5
for me, this one works pretty fine and is also valid for negative numbers:
public static double RoundToSignificantDigits(double number, int digits)
{
int sign = Math.Sign(number);
if (sign < 0)
number *= -1;
if (number == 0)
return 0;
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(number))) + 1);
return sign * scale * Math.Round(number / scale, digits);
}
My solution may be helpful in some cases, I use it to display crypto prices which vary greatly in magnitude - it always gives me a specified number of significant figures but unlike ToString("G[number of digits]") it doesn't show small values in scientific notation (don't know a way to avoid this with ToString(), if there is then please let me know!)
const int MIN_SIG_FIGS = 6; //will be one more for < 0
int numZeros = (int)Math.Floor(Math.Log10(Math.Abs(price))); //get number of zeros before first digit, will be negative for price > 0
int decPlaces = numZeros < MIN_SIG_FIGS
? MIN_SIG_FIGS - numZeros < 0
? 0
: MIN_SIG_FIGS - numZeros
: 0; //dec. places: set to MIN_SIG_FIGS + number of zeros, unless numZeros greater than sig figs then no decimal places
return price.ToString($"F{decPlaces}");
Here's a version inspired by Peter Mortensen that adds a couple of safeguards for edge cases such as value being NaN, Inf or very small:
public static double RoundToSignificantDigits(this double value, int digits)
{
if (double.IsNaN(value) || double.IsInfinity(value))
return value;
if (value == 0.0)
return 0.0;
double leftSideNumbers = Math.Floor(Math.Log10(Math.Abs(value))) + 1;
int places = digits - (int)leftSideNumbers;
if (places > 15)
return 0.0;
double scale = Math.Pow(10, leftSideNumbers);
double result = scale * Math.Round(value / scale, digits, MidpointRounding.AwayFromZero);
if (places < 0)
places = 0;
return Math.Round(result, places, MidpointRounding.AwayFromZero);
}
I just did:
int integer1 = Math.Round(double you want to round,
significant figures you want to round to)
Here is something I did in C++
/*
I had this same problem I was writing a design sheet and
the standard values were rounded. So not to give my
values an advantage in a later comparison I need the
number rounded, so I wrote this bit of code.
It will round any double to a given number of significant
figures. But I have a limited range written into the
subroutine. This is to save time as my numbers were not
very large or very small. But you can easily change that
to the full double range, but it will take more time.
Ross Mckinstray
rmckinstray01#gmail.com
*/
#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <cmath>
#include <iomanip>
#using namespace std;
double round_off(double input, int places) {
double roundA;
double range = pow(10, 10); // This limits the range of the rounder to 10/10^10 - 10*10^10 if you want more change range;
for (double j = 10/range; j< 10*range;) {
if (input >= j && input < j*10){
double figures = pow(10, places)/10;
roundA = roundf(input/(j/figures))*(j/figures);
}
j = j*10;
}
cout << "\n in sub after loop";
if (input <= 10/(10*10) && input >= 10*10) {
roundA = input;
cout << "\nDID NOT ROUND change range";
}
return roundA;
}
int main() {
double number, sig_fig;
do {
cout << "\nEnter number ";
cin >> number;
cout << "\nEnter sig_fig ";
cin >> sig_fig;
double output = round_off(number, sig_fig);
cout << setprecision(10);
cout << "\n I= " << number;
cout << "\n r= " <<output;
cout << "\nEnter 0 as number to exit loop";
}
while (number != 0);
return 0;
}
Hopefully I did not change anything formatting it.

Mod operator in C#

Is there a mod operator in C# for RSA algorithm? I've been using % as I thought this could be used as mod, but the answers I get for for c and m are not correct, so I've realised % doesn't work.
double e = 13;
double d; //decryption
double de = 7;
d = ((de * euiler) + 1) / e;
double message = 25;
double c = Pow(message, e) % n;
double m = Pow(c, d) % n;
The confusion lies in double Type.
MSDN:
The modulus operator (%) computes the remainder after dividing its first operand by its second. All numeric types have predefined modulus
operators.
Note the round-off errors associated with the double type.
the % is a remainder. You might want to make a static function that uses the % to make a modulo operation.

How to check my double variable is an integer or not? [duplicate]

This question already has answers here:
How to determine if a decimal/double is an integer?
(17 answers)
Get the decimal part from a double
(18 answers)
Closed 4 years ago.
I have a variable from:
double result = myList.Count / mySeptum;
I want to do the following:
if( result == int ) {
//Do Something...
}
else{
//Do another thing...
}
How can I do this?
I also tried this, but it didn't work:
if ( result%10 == 0 ){
...
}
In an example:
private void button2_Click(object sender, EventArgs e)
{
int r = 10;
int l = 2;
double d = r / l;
if (d % 10 == 0)
{
Console.WriteLine("INTEGER");
}
else
{
Console.WriteLine("DOUBLE");
}
}
For example:
double d = 1.0;
bool isInt = d == (int)d;
modulo:
double d = 1.0;
bool isInt = d % 1 == 0;
In general a floating point number on a computer can not represent every real number but only some discrete values. Thus, only for a few integers it will be possible that a double can be mathematically identical to an integer value. For most integers the closest double will be off by a small amount. So if you are looking for exact matches this will not work.
However, what you could do is to convert your double into an integer an check if the difference between the double and the integer is small enough:
double d = 1.5;
int i = (int) d;
double diff = d - i;
if (diff < 1.0e-6)
{
std::cout << "number is close to integer" << std::endl;
}
How to check my double variable is an integer or not?
From a C point of view (as post was originally tagged):
(I am certain C# has equivalent functions.)
To determine if a double is a whole number, use modf() to return the fractional part.
#include <math.h>
double x = ....;
double ipart;
if (isfinite(x) && modf(x, &ipart) == 0.0) {
// value is a whole number
....
To further test if it is in int range
if (ipart >= INT_MIN && ipart <= INT_MAX) {
int i = (int) ipart;
To check for wider integer types, we need some trickery to insure to no round-off error when forming the limits. Code takes advantage that INT..._MAX are Mersenne numbers
#define INT64_MAX_P1 ((INT64_MAX/2 + 1)*2.0)
if (ipart >= INT64_MIN && ipart < INT64_MAX_P1) {
int64_t i64 = (int64_t) ipart;
Try with typeOf:
if (myInt.GetType() == typeof(int))

Force Calculation to Round Up in C# [duplicate]

I want to round up double to int.
Eg,
double a=0.4, b=0.5;
I want to change them both to integer.
so that
int aa=0, bb=1;
aa is from a and bb is from b.
Any formula to do that?
Use Math.Ceiling to round up
Math.Ceiling(0.5); // 1
Use Math.Round to just round
Math.Round(0.5, MidpointRounding.AwayFromZero); // 1
And Math.Floor to round down
Math.Floor(0.5); // 0
Check out Math.Round. You can then cast the result to an int.
The .NET framework uses banker's rounding in Math.Round by default. You should use this overload:
Math.Round(0.5d, MidpointRounding.AwayFromZero) //1
Math.Round(0.4d, MidpointRounding.AwayFromZero) //0
Math.Round
Rounds a double-precision floating-point value to the nearest integral value.
Use a function in place of MidpointRounding.AwayFromZero:
myRound(1.11125,4)
Answer:- 1.1114
public static Double myRound(Double Value, int places = 1000)
{
Double myvalue = (Double)Value;
if (places == 1000)
{
if (myvalue - (int)myvalue == 0.5)
{
myvalue = myvalue + 0.1;
return (Double)Math.Round(myvalue);
}
return (Double)Math.Round(myvalue);
places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
} if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
{
myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
myvalue = (myvalue / Math.Pow(10, places + 1));
}
return (Double)Math.Round(myvalue, places);
}
Just some adjusting #BrunoLM's answer with more samples :
Math.Round(0.4); // =0
Math.Round(0.5); // =0
Math.Round(0.6); // =1
Math.Round(0.4, MidpointRounding.AwayFromZero); // = 0
Math.Round(0.5, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.6, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.4, MidpointRounding.ToEven); // = 0
Math.Round(0.5, MidpointRounding.ToEven); // = 0
Math.Round(0.6, MidpointRounding.ToEven); // = 1
Math.Round(0.5) returns zero due to floating point rounding errors, so you'll need to add a rounding error amount to the original value to ensure it doesn't round down, eg.
Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();
Another option:
string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33
string[] valStr = strVal.Split('.');
int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);
if (rightSide > 0)
leftSide = leftSide + 1;
return (leftSide);
It is also possible to round negative integers
// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply: c * a
// 2.) if c is negative: (c>0? subtract half of the dividend
// (b>>1) is bit shift right = (b/2)
// if c is positive: else add half of the dividend
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)
Extended from a tip somewhere else in here. Sorry, missed from where.
/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>
int main () {
//rounding negative int
// doing something like d = c * 3/4
int a=3;
int b=4;
int c=-5;
int d;
int s=c;
int e=c+10;
for(int f=s; f<=e; f++) {
printf("%d\t",f);
double cd=f, ad=a, bd=b , dd;
// d = c * 3/4 with double
dd = cd * ad / bd;
printf("%.2f\t",dd);
printf("%.1f\t",dd);
printf("%.0f\t",dd);
// try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
// doing div before mul on purpose
dd =(double)c * ((double)a / (double)b);
printf("%.2f\t",dd);
c=f;
// d = c * 3/4 with integer rounding
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
printf("%d\t",d);
puts("");
}
return 0;
}
/* test output
in 2f 1f 0f cast int
-5 -3.75 -3.8 -4 -3.75 -4
-4 -3.00 -3.0 -3 -3.75 -3
-3 -2.25 -2.2 -2 -3.00 -2
-2 -1.50 -1.5 -2 -2.25 -2
-1 -0.75 -0.8 -1 -1.50 -1
0 0.00 0.0 0 -0.75 0
1 0.75 0.8 1 0.00 1
2 1.50 1.5 2 0.75 2
3 2.25 2.2 2 1.50 2
4 3.00 3.0 3 2.25 3
5 3.75 3.8 4 3.00
// by the way evolution:
// Is there any decent small integer library out there for that by now?
It is simple. So follow this code.
decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);
Result is 11

How to round up value C# to the nearest integer?

I want to round up double to int.
Eg,
double a=0.4, b=0.5;
I want to change them both to integer.
so that
int aa=0, bb=1;
aa is from a and bb is from b.
Any formula to do that?
Use Math.Ceiling to round up
Math.Ceiling(0.5); // 1
Use Math.Round to just round
Math.Round(0.5, MidpointRounding.AwayFromZero); // 1
And Math.Floor to round down
Math.Floor(0.5); // 0
Check out Math.Round. You can then cast the result to an int.
The .NET framework uses banker's rounding in Math.Round by default. You should use this overload:
Math.Round(0.5d, MidpointRounding.AwayFromZero) //1
Math.Round(0.4d, MidpointRounding.AwayFromZero) //0
Math.Round
Rounds a double-precision floating-point value to the nearest integral value.
Use a function in place of MidpointRounding.AwayFromZero:
myRound(1.11125,4)
Answer:- 1.1114
public static Double myRound(Double Value, int places = 1000)
{
Double myvalue = (Double)Value;
if (places == 1000)
{
if (myvalue - (int)myvalue == 0.5)
{
myvalue = myvalue + 0.1;
return (Double)Math.Round(myvalue);
}
return (Double)Math.Round(myvalue);
places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
} if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
{
myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
myvalue = (myvalue / Math.Pow(10, places + 1));
}
return (Double)Math.Round(myvalue, places);
}
Just some adjusting #BrunoLM's answer with more samples :
Math.Round(0.4); // =0
Math.Round(0.5); // =0
Math.Round(0.6); // =1
Math.Round(0.4, MidpointRounding.AwayFromZero); // = 0
Math.Round(0.5, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.6, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.4, MidpointRounding.ToEven); // = 0
Math.Round(0.5, MidpointRounding.ToEven); // = 0
Math.Round(0.6, MidpointRounding.ToEven); // = 1
Math.Round(0.5) returns zero due to floating point rounding errors, so you'll need to add a rounding error amount to the original value to ensure it doesn't round down, eg.
Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();
Another option:
string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33
string[] valStr = strVal.Split('.');
int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);
if (rightSide > 0)
leftSide = leftSide + 1;
return (leftSide);
It is also possible to round negative integers
// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply: c * a
// 2.) if c is negative: (c>0? subtract half of the dividend
// (b>>1) is bit shift right = (b/2)
// if c is positive: else add half of the dividend
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)
Extended from a tip somewhere else in here. Sorry, missed from where.
/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>
int main () {
//rounding negative int
// doing something like d = c * 3/4
int a=3;
int b=4;
int c=-5;
int d;
int s=c;
int e=c+10;
for(int f=s; f<=e; f++) {
printf("%d\t",f);
double cd=f, ad=a, bd=b , dd;
// d = c * 3/4 with double
dd = cd * ad / bd;
printf("%.2f\t",dd);
printf("%.1f\t",dd);
printf("%.0f\t",dd);
// try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
// doing div before mul on purpose
dd =(double)c * ((double)a / (double)b);
printf("%.2f\t",dd);
c=f;
// d = c * 3/4 with integer rounding
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
printf("%d\t",d);
puts("");
}
return 0;
}
/* test output
in 2f 1f 0f cast int
-5 -3.75 -3.8 -4 -3.75 -4
-4 -3.00 -3.0 -3 -3.75 -3
-3 -2.25 -2.2 -2 -3.00 -2
-2 -1.50 -1.5 -2 -2.25 -2
-1 -0.75 -0.8 -1 -1.50 -1
0 0.00 0.0 0 -0.75 0
1 0.75 0.8 1 0.00 1
2 1.50 1.5 2 0.75 2
3 2.25 2.2 2 1.50 2
4 3.00 3.0 3 2.25 3
5 3.75 3.8 4 3.00
// by the way evolution:
// Is there any decent small integer library out there for that by now?
It is simple. So follow this code.
decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);
Result is 11

Categories

Resources