I want a function that is passed an integer, and if that integer is over a certain value (1000 in my current case) I want to perform some division on it so I can ultimately return an abbreviation of the original integer.
For example:
1000 = 1
1001 = 1
1099 = 1
1100 = 1.1
1199 = 1.1
1200 = 1.2
10000 = 10
10099 = 10
10100 = 10.1
It's the division and rounding side of things that has been causing me problems.
What would be the most suitable method to give me the results above?
How about:
int dividedBy100 = x / 100; // Deliberately an integer division
decimal dividedBy1000 = dividedBy100 / 10m; // Decimal division
string result = dividedBy1000.ToString();
I would advise using decimal here rather than float or double, as you fundamentally want decimal division by 10.
An abbreviation is by definition rounded.
If you are looking for more precision why not use Double instead of Integer?
Here's a suggestion
double function(int number)
{
if (number >= 1000)
{
return (((double)number) / 1000);
}
}
Your examples seem to imply that you only want one decimal place of precision, so how about something like this:
Divide by 100
Cast to double (or float)
Divide by 10
The first division will truncate any trailing numbers less than 100 (the equivalent of a 100-base floor function), then casting to double and dividing by 10 will give you the single decimal place of precision you want.
if t is the original number, then
int a=t/100
float b=a/10
b should contain your answer
Some more code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
while (true)
{
string s;
s = Console.ReadLine();
int a = Convert.ToInt32(s);
a = a / 100;
float b = a / (float)10.0;
Console.WriteLine(b);
}
}
}
}
You should use modular (remainder) mathematics to do this. You don't need to involve the FPU (Floating Point Unit).
static string RoundAndToString(int value, int denominator)
{
var remainder = value % denominator;
value = (value - remainder) / denominator;
if (remainder == 0)
return value.ToString();
remainder = (remainder * 10) / denominator;
return string.Format("{0}{1}{2}", value, CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, remainder);
}
Since you just want to truncate the number, it makes sense to convert it to a string, remove the last two characters from the string, then divide by 10 to get the corresponding number.
Here is the algorithm in Ruby. (I don't have C# handy)
a = 1000 #sample number
-> 1000
b = a.to_s[0..-3] #a converted to a string, then taking all characters except the last two.
-> "10"
c = b.to_i / 10.0 # converts to float in correct power
-> 1.0
You then display "c" in whatever format you want using sprintf (or the C# equivalent using FormatNumber).
try
int MyNumber = 10100;
string MyString = ((int) MyNumber/1000).ToString() + (( MyNumber % 1000) > 99 ? "." + (((int)( MyNumber / 100 )) % 10).ToString() : "");
Related
If I assign the value 0.1 to a float:
float f = 0.1;
The actual value stored in memory is not an exact representation of 0.1, because 0.1 is not a number that can be exactly represented in single-precision floating-point format. The actual value stored - if I did my maths correctly - is
0.100000001490116119384765625
But I can't identify a way to get C# to print out that value. Even if I ask it to print the number to a great many decimal places, it doesn't give the correct answer:
// prints 0.10000000000000000000000000000000000000000000000000
Console.WriteLine(f.ToString("F50"));
How can I print the exact value stored in a float; the value actually represented by the bit-pattern in memory?
EDIT: It has been brought to my attention elsewhere that you can get the behaviour I ask for using standard format strings... on .NET Core and .NET 5.0. So this question is .NET Framework specific, I guess.
Oops, this answer relates to C, not C#.
Leaving it up as it may provide C# insight as the languages have similarities concerning this.
How do I print the exact value stored in a float?
// Print exact value with a hexadecimal significant.
printf("%a\n", some_float);
// e.g. 0x1.99999ap-4 for 0.1f
To print the value of a float in decimal with sufficient distinctive decimal places from all other float:
int digits_after_the_decimal_point = FLT_DECIMAL_DIG - 1; // e.g. 9 -1
printf("%.*e\n", digits_after_the_decimal_point, some_float);
// e.g. 1.00000001e-01 for 0.1f
To print the value in decimal with all decimal places places is hard - and rarely needed. Code could use a greater precision. Past a certain point (e.g. 20 significant digits), big_value may lose correctness in the lower digits with printf(). This incorrectness is allowed in C and IEEE 754:
int big_value = 19; // More may be a problem.
printf("%.*e\n", big_value, some_float);
// e.g. 1.0000000149011611938e-01 for 0.1f
// for FLT_TRUE_MIN and big_value = 50, not quite right
// e.g. 1.40129846432481707092372958328991613128026200000000e-45
To print the value in decimal with all decimal places places for all float, write a helper function. Example.
// Using custom code
// -FLT_TRUE_MIN
-0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125
For .NET Framework, use format string G. Not exactly but enough for the float errors.
> (0.3d).ToString("G70")
0.29999999999999999
> (0.1d+0.2d).ToString("G70")
0.30000000000000004
Down voted... Fine, I find dmath, a math library for it.
> new Deveel.Math.BigDecimal(0.3d).ToString()
0.299999999999999988897769753748434595763683319091796875
The basic idea here is to convert the float value into a rational value, and then convert the rational into a decimal.
The following code (for .Net 6, which provides the BitConverter.SingleToUInt32Bits method) will print the exact value of a float (including whether a NaN value is quiet/signalling, the payload of the NaN and whether the sign bit is set). Note that the WriteRational method is not generally-applicable to all rationals as it makes no attempt to detect non-terminating decimal representations: this is not an issue here since all values in a float have power-of-two denominators.
using System; // not necessary with implicit usings
using System.Globalization;
using System.Numerics;
using System.Text;
static string ExactStringSingle(float value)
{
const int valueBits = sizeof(float) * 8;
const int fractionBits = 23; // excludes implicit leading 1 in normal values
const int exponentBits = valueBits - fractionBits - 1;
const uint signMask = 1U << (valueBits - 1);
const uint fractionMask = (1U << fractionBits) - 1;
var bits = BitConverter.SingleToUInt32Bits(value);
var result = new StringBuilder();
if ((bits & signMask) != 0) { result.Append('-'); }
var biasedExponent = (int)((bits & ~signMask) >> fractionBits);
var fraction = bits & fractionMask;
// Maximum possible value of the biased exponent: infinities and NaNs
const int maxExponent = (1 << exponentBits) - 1;
if (biasedExponent == maxExponent)
{
if (fraction == 0)
{
result.Append("inf");
}
else
{
// NaN type is stored in the most significant bit of the fraction
const uint nanTypeMask = 1U << (fractionBits - 1);
// NaN payload
const uint nanPayloadMask = nanTypeMask - 1;
// NaN type, valid for x86, x86-64, 68000, ARM, SPARC
var isQuiet = (fraction & nanTypeMask) != 0;
var nanPayload = fraction & nanPayloadMask;
result.Append(isQuiet
? FormattableString.Invariant($"qNaN(0x{nanPayload:x})")
: FormattableString.Invariant($"sNaN(0x{nanPayload:x})"));
}
return result.ToString();
}
// Minimum value of biased exponent above which no fractional part will exist
const int noFractionThreshold = (1 << (exponentBits - 1)) + fractionBits - 1;
if (biasedExponent == 0)
{
// zeroes and subnormal numbers
// shift for the denominator of the rational part of a subnormal number
const int denormalDenominatorShift = noFractionThreshold - 1;
WriteRational(fraction, BigInteger.One << denormalDenominatorShift, result);
return result.ToString();
}
// implicit leading one in the fraction part
const uint implicitLeadingOne = 1U << fractionBits;
var numerator = (BigInteger)(fraction | implicitLeadingOne);
if (biasedExponent >= noFractionThreshold)
{
numerator <<= biasedExponent - noFractionThreshold;
result.Append(numerator.ToString(CultureInfo.InvariantCulture));
}
else
{
var denominator = BigInteger.One << (noFractionThreshold - (int)biasedExponent);
WriteRational(numerator, denominator, result);
}
return result.ToString();
}
static void WriteRational(BigInteger numerator, BigInteger denominator, StringBuilder result)
{
// precondition: denominator contains only factors of 2 and 5
var intPart = BigInteger.DivRem(numerator, denominator, out numerator);
result.Append(intPart.ToString(CultureInfo.InvariantCulture));
if (numerator.IsZero) { return; }
result.Append('.');
do
{
numerator *= 10;
var gcd = BigInteger.GreatestCommonDivisor(numerator, denominator);
denominator /= gcd;
intPart = BigInteger.DivRem(numerator / gcd, denominator, out numerator);
result.Append(intPart.ToString(CultureInfo.InvariantCulture));
} while (!numerator.IsZero);
}
I've written most of the constants in the code in terms of valueBits and fractionBits (defined in the first lines of the method), in order to make it as straightforward as possible to adapt this method for doubles. To do this:
Change valueBits to sizeof(double) * 8
Change fractionBits to 52
Change all uints to ulongs (including converting 1U to 1UL)
Call BitConverter.DoubleToUInt64Bits instead of BitConverter.SingleToUInt32Bits
Making this code culture-aware is left as an exercise for the reader :-)
I'm very new with C#.
I don't understand why is x = 1 and not 1.4.
Can please somebody explain me this?
double x = (double)(12 / 5 - 3 % 2);
Console.WriteLine(x);
Because this is NOT about double.
You are integer-executing
(12 / 5 - 3 % 2);
and THEN casting to double. If you want this to be about double, then make sure at least one of the numbers is a double. In your case just mark the literals as double.
(12d / 5d - 3d % 2d);
is all doubles. As long as one is a double, the operation happens as double - but your original case makes all the calculations, THEN casts to double. So they happen as integer.
You're doing integer math and then converting to double. 12 / 5 = 2, 3 % 2 = 1, and 2 - 1 = 1.
Welcome to stackoverflow! :)
The problem is that you are operating all int, and afterwards converting them to double.
You need to make sure that you are operating with doubles from the beginning.
Try out the code in here: https://dotnetfiddle.net/xaQjKL
using System;
public class Program
{
public static void Main()
{
// Doubles from the beggining
double d_twelve = 12.0;
double d_five = 5.0;
double x = (double)(d_twelve / d_five);
Console.WriteLine($"Using all doubles: {x}");
// First split two int, then convert the result to double
int i_twelve = 12;
int i_five = 5;
x = (double)(i_twelve / i_five);
Console.WriteLine($"Using ints, and converting at the end to double: {x}");
// And now your code:
x = (double)(12 / 5 - 3 % 2);
Console.WriteLine($"Your original code: {x}");
// And now your code fixed (notice the 12 => 12.0):
x = (double)(12.0 / 5 - 3 % 2);
Console.WriteLine($"Changing 12 by 12.0: {x}");
}
}
You are doing operations with integers and then casting he result to a double.
double x = (12d / 5d - 3d % 2d);
Console.WriteLine(x);
Adding d after a number will make it a double while adding f will make it a float.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types#real-literals
Because you use integer values inside the parenthesis, and the expression is calculated using integer math before being cast to double.
You can use a double value for the first value and it should be enough:
> double x = (12d / 5) - (3 % 2);
> Console.WriteLine(x);
1.4
I am trying to round off below decimal number upto 4 decimal point. the below decimal no is
1.0715086071862673E+301 but when i am using Math.Round function.it's not working and returning same above no.please let me know how to round this no.
**code here:**
double s=2.0;
double ku = Math.Pow(s, 1000);
double jlk = Math.Round(ku, 4);
here depending on my logic i need only 1.0715 number.
Why do you round it ? Its a whole number anyway.
using System;
// referencing System.Numerics.dll
using System.Numerics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BigInteger bigInt = new BigInteger(2);
bigInt = BigInteger.Pow(bigInt, 1000);
Console.Out.WriteLine(bigInt.ToString());
}
}
}
Double val = 1.0715086071862673E+301
Math.Round(val / (10 ^ 297), 0) * (10 ^ 297))
The answer is going to be 1.0715E+301 ...
if you want it to be 1.0715, you would do
Double val = 1.0715086071862673E+301
Math.Round(val / (10 ^ 297), 0)
Additonally
This will work, but I wanted to point out that the conversion rounds in the process. (Also, this is vb.net - I'm not positive whether CType is how you convert in C#)
CType(CType((val / (10 ^ 297)) + 0.5, Long), Double) //Yields 1.0716
CType(CType((val / (10 ^ 297)), Long), Double) //Yields 1.0715
Use an appropriate type i.e. BigDecimal, src here Arbitrary-Precision Decimals in C#
I am trying to figure out what the best way is to parse a decimal value. I am currently using Math.Round, but that does not seem to work for the input data.
I want to be able to get the integer part and then the first digit after the decimal.
var value = 25.987817685360218441503885773M;
return Math.Round(value, 1);
returns 26 but I would like to return 25.9.
Presuming that you want to "round" it to 25.9 not to 26.9, you have to do it manually.
var number = 25.9877;
var rounded = Convert.ToDouble(Convert.ToInt32(number*10))/10;
And, of course, this is not rounding, this is just chopping off the decimals.
Edit:
Math.Round has an overload for that:
System.Math.Round (n, 2, MidpointRounding.ToEven);
See Math.Round Method
You are rounding which will obviously round at the end. What you want to do is truncate the number. Here is a method that will accomplish what you want:
public decimal TruncateDecimal(decimal value, int precision)
{
decimal step = (decimal)Math.Pow(10, precision);
int tmp = (int)Math.Truncate(step * value);
return tmp / step;
}
You are rounding to the first decimal, but 25.98 rounds UP. Which means 8 is >=5 and makes 9 become 0 and carry the one to 5. ie 5+1. Thus you are getting 26.
Since there at least to my knowledge is no working solution here which does what the OP wants.
// .NET has no build in power function for decimals
decimal Pow(decimal value, int exp)
{
if (exp < 0)
return 1/Pow(value, -exp);
if (exp == 0)
return 1;
else if (exp % 2 == 0)
return Pow(value * value, exp / 2);
else return
value * Pow(value, exp - 1);
}
// Rounds a number to decimals decimals, ie 1 => 1 decimal, -2 => whole hundreds
public decimal Truncate(decimal number, int decimals)
{
var factor = 1 / Pow(10, decimals);
return number - (number % factor);
}
Do keep in mind though that this is not rounding, this is some weird form of truncating.
I have tried using Math.Round & MidpointRounding. This does not appear to do what I need.
Example:
52.34567 rounded to 2 decimals UP = 52.35
1.183 rounded to 2 decimals DOWN = 1.18
Do I need to write a custom function?
Edit:
I should have been more specific.
Sometimes I need a number like 23.567 to round DOWN to 23.56.
In this scenario...
Math.Round(dec, 2, MidpointRounding.AwayFromZero) gives 23.57
Math.Round(dec, 2, MidpointRounding.ToEven) gives 23.57
Decimals up to 9 decimal places could come out and need to be rounded to 1, 2, 3 or even 4 decimal places.
Try using decimal.Round():
decimal.Round(x, 2)
Where x is your value and 2 is the number of decimals you wish to keep.
You can also specify whether .5 rounds up or down by passing third parameter:
decimal.Round(x, 2, MidpointRounding.AwayFromZero);
EDIT:
In light of the new requirement (i.e. that numbers are sometimes rounded down despite being greater than "halfway" to the next interval), you can try:
var pow = Math.Pow(10, numDigits);
var truncated = Math.Truncate(x*pow) / pow;
Truncate() lops off the non-integer portion of the decimal. Note that numDigits above should be how many digits you want to KEEP, not the total number of decimals, etc.
Finally, if you want to force a round up (truncation really is a forced round-down), you would just add 1 to the result of the Truncate() call before dividing again.
Try using Math.Ceiling (up) or Math.Floor (down). e.g Math.Floor(1.8) == 1.
Assuming you're using the decimal type for your numbers,
static class Rounding
{
public static decimal RoundUp(decimal number, int places)
{
decimal factor = RoundFactor(places);
number *= factor;
number = Math.Ceiling(number);
number /= factor;
return number;
}
public static decimal RoundDown(decimal number, int places)
{
decimal factor = RoundFactor(places);
number *= factor;
number = Math.Floor(number);
number /= factor;
return number;
}
internal static decimal RoundFactor(int places)
{
decimal factor = 1m;
if (places < 0)
{
places = -places;
for (int i = 0; i < places; i++)
factor /= 10m;
}
else
{
for (int i = 0; i < places; i++)
factor *= 10m;
}
return factor;
}
}
Example:
Rounding.RoundDown(23.567, 2) prints 23.56
For a shorter version of the accepted answer, here are the RoundUp and RoundDown functions that can be used:
public double RoundDown(double number, int decimalPlaces)
{
return Math.Floor(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
}
public double RoundUp(double number, int decimalPlaces)
{
return Math.Ceiling(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
}
Complete code with result.
double a = Math.Round(128.5, 0, MidpointRounding.AwayFromZero);
Result is 129
The Math class gives you methods to use to round up and down, they are Math.Ceiling() and Math.Floor() respectively. They work like Math.Round(), but they have a particularity, they only receive a value and round them to only the entire part.
So you need to use Math.Pow() to multiply the value by 10 to the n-esimal units you need to round power and then you need to divide by the same multiplied value.
Is important that you note, that the input parameters of the Math.Pow() method are double, so you need to convert them to double.
For example:
When you want to round up the value to 3 decimals (supposing value type is decimal):
double decimalsNumber = 3;
decimal valueToRound = 1.1835675M;
// powerOfTen must be equal to 10^3 or 1000.
double powerOfTen = Math.Pow(10, decimalsNumber);
// rounded must be equal to Math.Ceiling(1.1835675 * 1000) / 1000
decimal rounded = Math.Ceiling(valueToRound * (decimal)powerOfTen) / (decimal)powerOfTen;
Result: rounded = 1.184
When you want to round down the value to 3 decimals (supposing value type is decimal):
double decimalsNumber = 3;
decimal valueToRound = 1.1835675M;
// powerOfTen must be equal to 10^3 or 1000.
double powerOfTen = Math.Pow(10, decimalsNumber);
// rounded must be equal to Math.Floor(1.1835675 * 1000) / 1000
decimal rounded = Math.Floor(valueToRound * (decimal)powerOfTen) / (decimal)powerOfTen;
Result: rounded = 1.183
To reference how to use them more specificaly and to get more information and about both methods you can see these pages from the oficial MSDN Microsoft site:
Math Class
Math.Pow Method (Double, Double)
Math.Floor Method (Decimal)
Math.Floor Method (Double)
Math.Ceiling Method (Decimal)
Math.Ceiling Method (Double)
try this custom rounding
public int Round(double value)
{
double decimalpoints = Math.Abs(value - Math.Floor(value));
if (decimalpoints > 0.5)
return (int)Math.Round(value);
else
return (int)Math.Floor(value);
}
Maybe this?
Math.Round(dec + 0.5m, MidpointRounding.AwayFromZero);
You can achieve that by using the Method of Math.Round() or decimal.Round()-:
Math.Round(amt)
Math.Round(amt, Int32) and other overloading methods.
decimal.Round(amt)
decimal.Round(amt, 2) and other overloding methods.