155

I was testing what was returned from division including zeroes i.e. 0/1, 1/0 and 0/0. For this I used something similar to the following:

Console.WriteLine(1d / 0d);

However this code prints 8 not Infinity or some other string constant like PositiveInfinity.

For completeness all of the following print 8:

Console.WriteLine(1d / 0d);

double value = 1d / 0d;
Console.WriteLine(value);

Console.WriteLine(Double.PositiveInfinity);

And Console.WriteLine(Double.NegativeInfinity); prints -8.

Why does this infinity print 8?


For those of you who seem to think this is an infinity symbol not an eight the following program:

Console.WriteLine(1d / 0d);

double value = 1d / 0d;
Console.WriteLine(value);

Console.WriteLine(Double.PositiveInfinity);

Console.WriteLine(8);

Outputs:

Inifinity output

TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
  • 72
    You see `∞` is the sign of infinity. just flip it 90 degrees to see it 8 – Mohit S Dec 01 '16 at 09:57
  • Maybe when you rotate `8` you'll get the infinity symbol `∞`. – Cà phê đen Dec 01 '16 at 09:57
  • 24
    Are you sure it's an actual `8`, not some weird Unicode character for infinity, rotated 90 degrees? This could change based on your locale. I tried it on https://dotnetfiddle.net/ and it prints `Infinity`. – This company is turning evil. Dec 01 '16 at 09:58
  • Try converting `double` to `string` using neutral culture. – Sinatr Dec 01 '16 at 09:58
  • 1
    No 8 in my output. I do see the infinity symbol. – Patrick Hofman Dec 01 '16 at 10:01
  • @Kroltan See the edit showing my output – TheLethalCoder Dec 01 '16 at 10:03
  • 1
    I'm seeing `Infinity` text getting printed on my console. – RBT Dec 01 '16 at 10:03
  • 4
    @TheLethalCoder Please do what Sinatr suggested, or print the output of `Double.PositiveInfinity.ToString()[0] == '8'`. There are some exotic characters that look very similar to others in some fonts. Also, what language is your computer configured to? – This company is turning evil. Dec 01 '16 at 10:09
  • 16
    This seems to be a Windows 10 problem. In Windows 8.1 I had an infinity symbol. Upgraded a few days ago to Windows 10 and now I have an `8`, too (german locale). – René Vogt Dec 01 '16 at 10:12
  • @RenéVogt I am on Windows 10 too so that could be the case, UK locale though – TheLethalCoder Dec 01 '16 at 10:13
  • 1
    maybe try changing the font in the console properties. – Slai Dec 01 '16 at 10:21
  • 1
    @Slai I investigated differences between windows 8 and 10 and the console windows do use different default fonts as far as I can tell so this could be what is causing the 'issue' – TheLethalCoder Dec 01 '16 at 10:56
  • 14
    A quick check would be to see what happens for `Console.Write("∞");` – Jon Hanna Dec 01 '16 at 15:25
  • @CodyGray I'd argue that the "infinity" tag is more of a meta tag so I have removed it, if you feel it should be on the question feel free to edit it back in – TheLethalCoder Dec 01 '16 at 16:12
  • It is your console's current codepage issue. Can you post the output of the following command in console: `chcp`. Also try running this command in console prior to running your program: `chcp 65001` – Salman A Dec 01 '16 at 16:36
  • @René Vogt: I tested on various other PC's both Windows 10 and not and I only see the `8` on Windows 10 PC's. Therefore I believe this to be a "problem" in Windows 10. The change could be due to a font change between Windows 8.1 and Windows 10 and looking into the fonts of the console window they are different so this could be the issue. – TheLethalCoder Dec 01 '16 at 10:38
  • @LưuVĩnhPhúc It appears it is a font/code page issue but it happens with the default ones in windows 10. So I wouldn't really call it a bug, with windows 10 at least – TheLethalCoder Dec 01 '16 at 16:57
  • well a font render or code transformation issue is still a bug – phuclv Dec 01 '16 at 17:00
  • 1
    if it only appears in Win10 then you should really press win+F to open the feedback hub and file a bug – phuclv Dec 01 '16 at 16:52
  • In WinXP, most locales said `Infinity` or their local equivalent, but the Japanese got `+∞` even then. So I guess they'd be even more bothered by the `8` they get now. – Mark Hurd Dec 26 '16 at 06:01
  • 2
    @LưuVĩnhPhúc I have [reported it](https://aka.ms/J6hdon) to Windows Feedback. – Mark Hurd Jan 11 '17 at 12:04
  • @MarkHurd I didn't want to have to create an account just to do it, so thanks – TheLethalCoder Jan 11 '17 at 12:42
  • Having run into the same issue, I copied the character into the calculator. If it wasn't an 8, it would display "Invalid Input". Definitely being converted to an 8. The weird thing is that it is displayed correctly as an infinity symbol in the debugger. – AaronF Apr 02 '17 at 03:29
  • @AaronF what you copied is output of console. In that matter Windows somewhat similar to linux. A console is a visualizer of input stream. What you get wasn't what it received. It processes all control characters, etc. Debug console in IDE uses different procdure, it doesn't receive output from another console, it receives original data stream. Even tHe black console window that appears whe you debug console app in MSVC is a separate "console stub" executable with slightly different behaviour. THis leads to certain level of "software gore". – Swift - Friday Pie Jul 14 '23 at 07:47

7 Answers7

114

Be assured that the floating point value is +Infinity if the numerator of a floating point division by zero is positive, -Infinity if the numerator of a floating point division by zero is negative, and NaN if the numerator and denominator of a floating point division are both zero. That's in the IEEE754 floating point specification, which is what C# uses.

In your case, the console is converting the infinity symbol (which is sometimes represented typographically as a horizontal 8 — ∞) to a vertical 8.

Vadim Pushtaev
  • 2,332
  • 18
  • 32
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 13
    @TheLethalCoder The picture doesn't disprove this answer, since it's a picture of your console – Rob Dec 01 '16 at 10:03
  • 10
    @Rob I misread the answer, however that begs the questions, why does it convert it to an 8? And why do some fiddles/consoles print the string literal – TheLethalCoder Dec 01 '16 at 10:04
  • 1
    This seems to be the case using the debugger I see an infinity symbol (i.e. the horizontal 8), is there any reason my console would convert to an 8 whilst everyone else's seems to use `Infinity` or similar even if I use the code from the answer by Soren by specifying the culture – TheLethalCoder Dec 01 '16 at 10:13
  • 5
    It's called a "lemniscate". It has a unicode value: ∞ – BlueRaja - Danny Pflughoeft Dec 01 '16 at 10:58
  • 15
    This probably explains why Buzz Lightyear says "To Eight And Beyond!" when I play Toy Story on my PC. ;) – DeanOC Dec 06 '16 at 19:44
72

Given certain settings (i.e. combination of cultures, output encoding, etc.) .NET will output the Unicode infinity character ∞ (∞ / ∞). The Windows 10 console/terminal emulator will (again given certain settings - see screenshot below) display this Unicode character as an 8.

For example, on Windows 10, with the below settings (note the code page) simply pasting ∞ into the console shows as 8.

Setting to reproduce

EDIT

With thanks to comment from Chris: It seems that the output font in combination with the code page is responsible for the ∞ => 8 issue on the console. Like him I get proper display of ∞ in all the TrueType fonts I have tried and only see 8 when raster fonts' is chosen.

font settings

Community
  • 1
  • 1
tolanj
  • 3,651
  • 16
  • 30
  • 1
    Mine actually shows the infinity sign on its side instead of an "8" when pasted in the console, though I'm using "437 (OEM - United States)" – Derek 朕會功夫 Dec 03 '16 at 11:08
  • 3
    Though the answer is right that certain settings can cause this display issue the second half is incorrect. My options currently look exactly the same as yours above and I get the correct ∞ rather than an 8. I can only get it to show an 8 if I go to the fonts page and choose "raster fonts" from the list of available fonts. Consolas, Courier New and others all seem to display it fine... – Chris Dec 04 '16 at 02:46
  • It's definitely a combination of the two factors, because setting the font to Raster when the codepage is 437 still shows the symbol correctly. Only if *both* conditions are met does this seem to happen (at least for me). – Moshe Katz Dec 06 '16 at 18:43
42

The 8 symbol occurs when Windows converts Unicode to a legacy character encoding. Since there is no infinity symbol in the legacy encoding, it uses a "best fit" to that symbol, by default, which in this case is the number 8. See an example for Microsoft's "windows-1252" encoding. Apparently, Windows 10 still uses legacy character encodings by default in the console (see "Code Pages").

gdir
  • 922
  • 2
  • 17
  • 25
Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • 12
    I wonder why "8" is considered a good fit, when it is semantically so apt to generate confusion? Other characters in code page 437 would seem a better fit, like the degree sign or the per-mille sign (a % with two o's below the slash). Neither of those would be as good as an actual infinity sign, but they'd seem less prone to cause confusion. – supercat Dec 02 '16 at 00:26
  • _"Apparently, Windows 10 still uses legacy character encodings by default in the console"_ Nope, my Windows 10 cmd.exe has legacy encoding turned off out of the box. – Lightness Races in Orbit Dec 03 '16 at 17:59
  • 1
    This is the best answer IMHO. Actually, you can also see the '8' character at position 0x2440 at least on my Windows 10 box in the c:\windows\system32\c_1252.nls file (*infinity* is 0x221E, and the file has some header that explains the offset). All codepage encoding have a corresponding .nls file. By default, the console uses 1252 code page (Windows 1252). Note these mappings won't be maintained, check this: https://blogs.msdn.microsoft.com/shawnste/2007/09/24/are-we-going-to-update-or-maintain-the-best-fit-or-code-page-mappings/ – Simon Mourier Dec 28 '16 at 07:38
35

Note: The implicit .ToString() method call when writing Double.PositiveInfinity to console is responsible for this behavior.

Calling Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("en-Us")));

results in the string "Infinity"

while Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); results in "+Infini".

Edit: As others have pointed out in the commets, they cannot entirely confirm my results. Testing this on a different machine, I get the character for both calls.

Output for all cultures, thanks to vtortola in the comments.


I found a (likely) answer:

Using Console.OutputEncoding = Encoding.Unicode; I can recreate the behavior you are experiencing for several cultures, e.g. "ru", "ru-RU" produce the output 8.

Community
  • 1
  • 1
Søren D. Ptæus
  • 4,176
  • 1
  • 26
  • 28
  • 1
    Out of interest I tried your examples and they both print 8 – TheLethalCoder Dec 01 '16 at 10:07
  • 1
    @TheLethalCoder I get `Infinity` in both. Which is the culture your app is running? Check `Thread.CurrentThread.CurrentCulture` and `Thread.CurrentThread.CurrentUICulture` . – vtortola Dec 01 '16 at 10:09
  • 8
    @Søren D. Ptæus tbh I cannot see any culture generating an `8` https://dotnetfiddle.net/QYhXMu – vtortola Dec 01 '16 at 10:16
  • 1
    You are right about the implicit `.ToString()`. In the end, `ToString()` will return the `.PositiveInfinitySymbol` of the relevant `NumberFormatInfo`. These seem to depend on the version of the runtime and/or the version of Windows (or whatever OS). In the old days, `CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbol` would be equal to `"Infinity"`, but with newer versions of the runtime and operating system it is `"∞"` instead. I just asked about it in a comment to Hans Passant's answer in this thread. – Jeppe Stig Nielsen Jul 12 '18 at 12:35
17

Repro code:

using System;
using System.Text;

class Program {
    static void Main(string[] args) {
        var infinity = "\u221e";
        Console.OutputEncoding = Encoding.GetEncoding(1252);
        Console.WriteLine(infinity);
        Console.ReadLine();
    }
}

Code page 1252 is a pretty common accident in England since it is the default Windows code page there. As it is for Western Europe and the Americas. Lots of reasons to change the default Console.OutputEncoding property programmatically, many text files will be encoded in 1252. Or from the command line by typing chcp 1252 (chcp == change code page) before starting the program.

As you can tell from the character set supported by 1252, the Infinity symbol is not available. So the Encoding has to come up with a substitute. That is often the ? glyph for unsupported Unicode codepoints, the Encoding.EncoderFallback property value for 8-bit encodings. But for 1252, and the legacy MS-Dos 850 and 858 code pages, the Microsoft programmer decided for 8. Funny guy.

The glyph is supported in the usual code page for console apps on a Western machine. Which is 437, matches the legacy IBM character set. Having these kind of encoding disasters is why Unicode was invented. Sadly too late to rescue console apps, far too much code around that relied on the default MS-Dos code page.

Having Double.PositiveInfinity converted to "∞" is specific to Win10. It used to be "Infinity" in previous Windows versions. These kind of formats can normally be modified with Control Panel > Language > Change date, time, or number formats > Additional Settings button but the infinity symbol selection is not included in the dialog. Also not covered by the registry (HKCU\Control Panel\International), rather a big oversight. It is LOCALE_SPOSINFINITY in the native winapi. In a .NET program you can override it programmatically by cloning the CultureInfo and changing its NumberFormatInfo.PositiveInfinitySymbol property. Like this:

using System;
using System.Text;
using System.Threading;
using System.Globalization;

class Program {
    static void Main(string[] args) {
        Console.OutputEncoding = Encoding.GetEncoding(1252);
        var ci = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
        ci.NumberFormat.NegativeInfinitySymbol = "-Infinity";
        ci.NumberFormat.PositiveInfinitySymbol = "And beyond";
        Thread.CurrentThread.CurrentCulture = ci;
        Console.WriteLine(1 / 0.0);
        Console.ReadLine();
    }
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Your code allowed me to confirm WinXP uses code page 437, which, in Windows 10, now prints `ý` instead of `∞`. It also showed me that using non-raster fonts avoids the problem. – Mark Hurd Dec 26 '16 at 07:15
  • Is it the version of the .NET runtime, or the version of Windows (or whatever OS), or a combination, that determines whether `CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbol` gives `"Infinity"` or `"∞"` (or something else)? You say above that it is specific to Windows 10, and I do agree it was changed at some time. But if I run an application on Windows 8 _with "the same" version of the .NET Framework_, will I get a different result than with Windows 10? – Jeppe Stig Nielsen Jul 12 '18 at 12:27
  • This problem starts with Windows, then exposes a quirk in .NET. Win8 still favors "Infinity" – Hans Passant Jul 12 '18 at 12:35
  • 1
    Confirmed! I just logged into a Windows Server 2012 R2 machine (corresponds roughly to Windows 8.1), and I know it has the newest .NET Framework, and it also has the newest Windows PowerShell. In PowerShell, `$PSVersionTable` reveals the PS version is something with 5.1. That PowerShell targets the .NET Framework (CLR) version 4.* which I know is new on that machine. Still `[cultureinfo]::GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbol` from Windows PowerShell gives `Infinity`, not `∞` (current culture is `en-US`). Conclusion: Windows version decides, not .NET version. – Jeppe Stig Nielsen Jul 12 '18 at 13:23
2

This has to do with your Windows 10 region settings.

Tested on Windows 10 Pro version 2004. I've just solved it by doing the following:

  1. Goto 'Region Settings' by typing it in start.
  2. Click on 'Additional date, time & regional settings'
  3. Click on 'Change date, time or number formats'
  4. Goto 'Administrative' tab
  5. Click 'Change system locale'
  6. Check the box for 'Beta: Use Unicode UTF-8 for worldwide language support'

Restart your PC, now your 8 will print as ∞

Deman
  • 21
  • 1
0

"8" for infinity is displayed in the console when running .Net 4 and above, otherwise previous versions display "Infinity".

Using Console.OutputEncoding = Encoding.Unicode; in .Net 4 and above will get infinity to display as ∞, but throws an IOException in previous versions.

NOTE: I'm running Visual Studio 2015 Community Edition on Windows 10 64-bit

Dave Russell
  • 141
  • 1
  • 8