String Format C# Small Negative Values - c#

Why does the following program not output the negative sign for the second line?
var smallpos = 3.65433E-005;
var smallneg = -3.65433E-005;
Console.WriteLine("{0} in F4 format with a width of 8 characters {1}",
smallpos,
smallpos.ToString("F4").PadLeft(8).Substring(0, 8));
Console.WriteLine("{0} in F4 format with a width of 8 characters {1}",
smallneg,
smallneg.ToString("F4").PadLeft(8).Substring(0, 8));
Using VS 2017 Professional 15.8.2 C# 7.2

-3.65433E-005 represents -0.0000365433.
The issue here is with smallneg.ToString("F4"). It only considers the first 4 places after the decimal point; since they're all 0 the negative sign is left out as -0 wouldn't make much sense.

Once you've eliminated enough digits from the back, the remaining number will have a value of zero, at which point the existence of a "-" has no real meaning.
This can be understood quite intuitively by running the snippet below, which has a decreasing number provided for the fixed-point specifier.
In the last line, that specifier is omitted, at that point NumberFormatInfo.NumberDecimal decides the number of decimal places used (depending on the culture used):
var smallneg = -3.65433E-005;
Console.WriteLine(smallneg.ToString("F10")); // -0,0000365433
Console.WriteLine(smallneg.ToString("F9")); // -0,000036543
Console.WriteLine(smallneg.ToString("F8")); // -0,00003654
Console.WriteLine(smallneg.ToString("F7")); // -0,0000365
Console.WriteLine(smallneg.ToString("F6")); // -0,000037
Console.WriteLine(smallneg.ToString("F5")); // -0,00004
Console.WriteLine(smallneg.ToString("F4")); // 0,0000 <-- Zero --> (-0) == 0
Console.WriteLine(smallneg.ToString("F")); // 0,00

Related

How do i print out the decimal part of a number to a certain number of digits in C Sharp C#

Can someone help me out ?
How do I print out the decimals of a number to a certain number of decimals in C# or should i say, how do you add trailing zeros to meet the specified number.
Example: printing to 7 decimals
5.66 should return 0.6600000
0.123456 should return 0.1234560
A simple way to specify the number of digits is to use a custom formatting string. '0' is a placeholder for a digit to always print, '#' would be an digit to print if relevant. So 7 decimals would be "0.0000000", There are also standard formatting strings that may be useful.
If you are not interested in the whole number part you can just subtract it:
var decimalPart = myValue - (int)myValue;
var str = decimalPart.ToString("0.0000000");
i found the solution. You use the float function.
int double= Convert.ToDouble(Console.ReadLine());
Console.WriteLine($"{num:fn}");
f specifies a float
n specifies the number of decimal places.
so f4 = to 4 decimal places

In C#, how can I format integers with zero-padding without making negative values longer?

I'm working in C# .Net 5.0, Visual Studio. I'm formatting integers to have zero-padding like so
$"{-1:d04}"
$"{1:d04}"
Formatting positive and negative numbers give different lengths of the resulting strings
-0001
0001
I need my numbers to be the same length (i.e. the result in this example should be the strings "-001" and "0001"), does there exist any formatting pattern to achieve this?
One way is to use the ; specifier to provide two formats for non-negative and negative numbers.
int x = 1;
Console.WriteLine($"{x:0000;-000}"); // "0001"
x = -1;
Console.WriteLine($"{x:0000;-000}"); // "-001"
0000 for positive numbers, -000 for negative numbers.
This does mean that you no longer use the standard format specifier D, which automatically uses the NegativeSign from the current NumberFormatInfo. You'd have to hardcode the negative sign in. This may or may not be a problem depending on what you are doing.
Edit:
Apparently this is for sorting strings. If the format doesn't have to be exactly "0001" and "-001", and just has to be the same length, then I suggest:
int x = 1;
Console.WriteLine($"{x,5:d04}"); // " 0001" (note the leading space)
x = -1;
Console.WriteLine($"{x,5:d04}"); // "-0001"

Rounding floats with `E` in C#

I've got 7,0975401565468943E+22
And Math.Round(x, 3) returns 7,0975401565468943E+22
Is it normal behavior and should I check if number contains E and if so just use something alike ToString("N2"); ?
code example:
float flo = float.Parse( " 7,0975401565468943E+22 " );
double flox = Math.Round(flo, 3);
The behavior you describe appears normal (though without a code example it is impossible to know for sure).
Your number has no significant digits in the fractional portion, as displayed. Note the "E+22", this means that you are dealing with a very large number. There are only 17 significant digits displayed, with another 5 digits not shown before you get to the decimal point. You can round to as many fractional digits as you want, you won't see any change in the number being displayed.

Parsing floats with Single.Parse()

Here comes a silly question. I'm playing with the parse function of System.Single and it behaves unexpected which might be because I don't really understand floating-point numbers. The MSDN page of System.Single.MaxValue states that the max value is 3.402823e38, in standard form that is
340282300000000000000000000000000000000
If I use this string as an argument for the Parse() method, it will succeed without error, if I change any of the zeros to an arbitrary digit it will still succeed without error (although it seems to ignore them looking at the result). In my understanding, that exceeds the limit, so What am I missing?
It may be easier to think about this by looking at some lower numbers. All (positive) integers up to 16777216 can be exactly represented in a float. After that point, only every other integer can be represented (up to the next time we hit a limit, at which point it's only every 4th integer that can be represented).
So what has to happen then is the 16777218 has to stand for 16777218∓1, 16777220 has to stand for 16777220∓1, etc. As you move up into even larger numbers, the range of integers that each value has to "represent" grows wider and wider - until the point where 340282300000000000000000000000000000000 represents all numbers in the range 340282300000000000000000000000000000000∓100000000000000000000000000000000, approximately (I've not actually worked out what the right ∓ value is here, but hopefully you get the point)
Number Significand Exponent
16777215 = 1 11111111111111111111111 2^0 = 111111111111111111111111
16777216 = 1 00000000000000000000000 2^1 = 1000000000000000000000000
16777218 = 1 00000000000000000000001 2^1 = 1000000000000000000000010
^
|
Implicit leading bit
That's actually not true - change the first 0 to 9 and you will see an exception. Actually change it to anything 6 and up and it blows up.
Any other number is just rounded down as float is not an 100% accurate representation of a decimal with 38+1 positions that's fine.
A floating point number is not like a decimal. It comprises a mantissa that carries the significant digits and an exponent that effectively says how far left or right of the decimal point to place the mantissa. A System.Single can only handle seven significant digits in the mantissa. If you replace any of your trailing zeroes with an arbitrary digit it is being lost when your decimal is converted into the mantissa and exponent form.
Good question. That is happening because the fact you can save a number with that range doesn't mean this type'll have enough precision to hold it. You can only store ~6-7 leading digits for floats and add an exponent to describe decimal point position.
0.012345 and 1234500 hold the same amount of informations - same mantissa, different exponents. The MSDN states only that value AFTRER EXPONENTIATION cannot be bigger, than MaxValue.

c#: string format

I came across a code. Can anybody shed a bit of light on it. Plz be kind if anybody finds it a bit basic.
string str= String.Format("{0,2:X2}", (int)value);
Thankyou for your time.
X format returns Hexadecimal representation of your value.
for example String.Format("{0:X}", 10) will return "A", not "10"
X2 will add zeros to the left, if your hexadecimal representation is less than two symbols
for example String.Format("{0:X2}", 10) will return "0A", not "A"
0,2 will add spaces to the left, if the resulting number of symbols is less than 2.
for example String.Format("{0,3:X2}", 10) will return " 0A", but not "0A"
So as result this format {0,2:X2} will return your value in Hexadecimal notation appended by one zero from the left if it is only one symbol and then appended by space from the left if is it one symbol. After reading this several times, you can see, that ,2 is redundant and this format can be simplified to {0:X2} without changing the behavior.
Some notes:
: separates indexing number and specific format applied to that object. For example this code
String.Format("{0:X} {1:N} {0:N}", 10, 20)
shows, that I want to format 10 (index 0) in hexadecimal then show 20 (index 1) in numerical way, and then also format 10 (index 0) in numeric way.
0,2 from the left part of semi-column indicated index position 0 and format ,2 applied to the resulting string, not to a specific object. So this code
String.Format("{0,1} {1,2} {0,4}", 10, 20)
will print first number with at least one symbol, second with at least two symbols and then again first number with at least four symbols occupied. If the number of symbols in resulting string will be less - they will be populated by spaces.
{0,2:X2}
It splits into
0,2 - Format a number 10 into 10
X2 - Formats a number 10 into hexadecimel value 0A.
Update
Code
String.Format("{0,2:X2}", (int)value); // where value = 10
Result: 0A
Live Example: http://ideone.com/NW0U26
Conclusion from me
You can change "{0,2:X2}" to "{0:X2}", live example here.
Reference Links: MSDN
According to MSDN, a format string has the following format:
{index[,alignment][:formatString]}
We can find all of these components (the last two being optional) in your format string:
0 is the index of the parameter to use.
,2 is the alignment part, if the result is shorter than that, it is padded left with spaces.
:X2 is the formatString part. It means the number will be formatted in hexadecimal (uppercase) format, with a minimum width of 2. If the resulting number has less than 2 digits, it is padded with zeroes on the left.
In this specific case the alignment specifier is redundant, because X2 already specifies a minimum width of 2.
See here for more info on the format string:
Composite Formatting
Standard Numeric Format Strings

Categories

Resources