11

While I was programming in C++ some days ago, I made this mistake (that I have history of making it!). In one part of my code, I had 1/6 and I was expecting it be 0.16666666666 which is not the case. As you all know the result is 0 - C, C++, Java, Python, all behave the same.

I post it on my Facebook page and now there is debate on if there is a programming language where 1/6 behaves the same as 1.0/6.0.

5
  • 5
    Haskell. 1 / 6 = 0.16666666666666666
    – t123
    Aug 9, 2012 at 8:22
  • PowerShell generates 0.166666666666667, which surprised me as 1 is an integer. I'd wager there's some other .NET languages which generate the value you expected.
    – JohnL
    Aug 9, 2012 at 14:53
  • There is, in theory, an unlimited number of them.. Here's another: Rebol, as well as derivatives like Orca, Red, and so on. >> 1 / 6 -> == 0.166666666666667
    – Izkata
    Aug 9, 2012 at 15:05
  • Lua does this. It only has a single Number type, that usually is the same as C's double.
    – Machado
    Aug 16, 2012 at 19:49
  • In Clojure 1/6 is actually 1/6 (fractional type) which, coerced to Double, is 1.66666...
    – kaoD
    Aug 16, 2012 at 20:40

13 Answers 13

18

Has everyone forgotten Pascal?

1/6 yields 0.1666666... (to whatever precision is supported).

1 div 6 yields 0

It's arguable whether the C rule is a mistake. Almost all of C's arithmetic operators, where the operands are of the same type, yield a result of the same type. There's something to be said for consistency.

Furthermore, since C is primarily targeted at system-level code, most C programs don't use floating-point at all. At one time, accidentally adding floating-point code to a program that didn't otherwise need it could be a serious problem. That's probably still the case, for small embedded systems -- which, again, are a major target for C.

In most C programs, truncating integer division is probably just what you want anyway.

If 1 / 6 yielded a floating-point result in C, then:

  • It would be an inconsistency in the language.
  • The standard would have to make an arbitrary choice of which floating-point type to use for the result (double may seem like the natural choice, but you might prefer the extra precision of long double)
  • The language would still have to have an operation for integer division; performing floating-point addition and then truncating would likely not be good enough.

C could have provided separate operators for the two kinds of division, but the second point above would still apply: which of the three floating-point types would be used for the result? And since it's easy enough to get floating-point division if you need it (use a floating-point constant for one or both of the operands, or cast one or both of the operands to a floating-point type), it apparently wasn't considered that important.

In the 1974 version of the C manual (that's 4 years before the publication of the first edition of K&R), Ritchie doesn't even mention the possible confusion:

The binary / operator indicates division. The same type considerations as for multiplication apply

which says that if both operands are of type int or char, the result is of type int.

Yes, it's a source of confusion for some C programmers, especially beginners -- but C is not noted for being very novice-friendly.

4
  • 5
    Pascal. Getting details right before C got them wrong.™ Aug 9, 2012 at 17:44
  • And then Algol was an improvement over its successors (in the number of which both C and Pascal stand). Aug 9, 2012 at 18:24
  • Pascal - getting the details right (give or take a factor of 10) Aug 9, 2012 at 18:46
  • 1
    I originally wrote 1.666666..., which is clearly wrong. My lame excuse is that the Pascal test program I wrote printed 1.6666666666666667E-0001 Aug 9, 2012 at 19:42
17

Actually this behavior was changed in Python 3 and it now does behave like you expect (// is now used for integer division).

2
  • Thanks. Any other programming languages do you have in you mind? Basic family maybe?
    – Pouya
    Aug 9, 2012 at 8:22
  • 1
    @Pouya: This behavior is standard for the Pascal family. / always produces a floating-point value, and a separate operator (div) is used for integer division. Aug 9, 2012 at 18:18
14

Out of prominent languages, JavaScript. 1.0/6.0 = 1/6 = 0.16666666666666666.

I don't see this as surprising. As a rule of a thumb, if a language distinguishes between integer and floating point numeric types, dividing two integers will yield a truncated integer instead of float. If it doesn't, most likely it will default to floating point operations. This should be the expected behaviour on the programmer's part.

Just keep in mind that there are additional things that could also be at play here, like the already mentioned separate integer division operator or implicit type casting.

16
  • 6
    This is not "a rule of thumb". It's a rule of C, and a handful of languages that blindly copied C's mistakes. Aug 9, 2012 at 17:48
  • 4
    @MasonWheeler: Did FORTRAN "blindly copy C's mistake"? I personally believe that well-designed languages should use separate operators for truncated division versus approximate division of integer quantities (and also, btw, for value and referential equality), but the design decision in the days of FORTRAN was probably reasonable. That doesn't mean every language should do things the way FORTRAN did in the 1950's.
    – supercat
    Aug 9, 2012 at 18:40
  • 3
    Lower level languages need to make these distinctions. Higher level/dynamic languages are often better off without them. It's a design trade-off. I appreciate just having one big dumb Number constructor/type in JS, but I imagine I'd be feeling JS was lacking when trying to write a high performance 3D engine without stricter type control. JS may have overlapping utility with other languages but I don't think anybody is ever going to consider it a goto for writing high performance closer-to-the-chrome type stuff. Aug 9, 2012 at 20:15
  • 2
    Mathematics outside of programming considers integer-only rules for division. Aug 9, 2012 at 20:36
  • 5
    @MasonWheeler: Programming is not pure math. Mathematically, 1/6 is a rational number and cannot be exactly represented by binary floating point number. The only precise representation is as a ratio with a denominator six times the numerator. Aug 9, 2012 at 21:48
7

There are many languages where ((1/6)*6) results in 1, not in 0. For example, PL/SQL, many BASIC dialects, Lua.

Accidentally, in all those langauges 1/6 results in .166666667, or 0.16666666666667 or something similar. I chose the ((1/6)*6)==1 variant to get rid of those little differences.

9
  • 7
    That's not the question.
    – Roc Martí
    Aug 9, 2012 at 8:13
  • 20
    Accidentally, in all those langauges 1/6 results in .166666667, or 0.16666666666667 or something similar. I chose the ((1/6)*6)==1 variant to get rid of those little differences, but it looks like I overestimated the math skills of some people.
    – user281377
    Aug 9, 2012 at 8:49
  • 1
    @RocMartí yes, it really is...
    – MattDavey
    Aug 9, 2012 at 15:11
  • 1
    I would be surprised to see (1.0/6.0)*6 being exactly equal to 1! The rounding of the result of (1.0/6.0) will lead to a small difference. (Although there will be a few languages that default to infinite precision)
    – Sjoerd
    Aug 9, 2012 at 17:49
  • 2
    @Sjoerd: It's not too surprosing that it's exact, actually. Consider in decimal the scenario of 1/11 * 11 with all values accurate to five significant figures. The value of 1/11 is 9.0909 * 10^-2. Multiply by 11 and one would get 99.9999 * 10/-2 before rounding. Round to five significant figures and the result will be 1.0000 * 10^0. Note that the key is that the mantissa of 1/6 is "...0101010101...". If the last bit of a representation is a "1", multiplying it by six and rounding will yield 1. If the last bit were zero, it would not.
    – supercat
    Aug 9, 2012 at 18:46
3

Haskell treats 1/6 and 1.0/6.0 as being identically 0.16666666666666666. It also renders 1/6.0 and 1.0/6 as being that same value as well.

This is due to the basic numerical types in Haskell not being quite the same as other languages. True integer division is somewhat...complicated.

2

Yes, Perl does. The one-liner

perl -e '$x=1/6;print "$x\n";'

results in the output of:

0.166666666666667

I believe that PHP works the same way.

Edited to add: I also believe that a necessary (but not sufficient) condition for 1/6 == 1.0/6.0 is for the language in question to be weakly typed.

8
  • Why the heck would weak typing (whatever that's supposed to mean) be necessary? Just define / to (also) mean float division in the case of both arguments being integers.
    – user7043
    Aug 9, 2012 at 8:55
  • 1
    @delnan - en.wikipedia.org/wiki/Weak_typing I suppose it might be possible to have a strongly typed language in which / is automatically overloaded depending on the types of the arguments, but that seems like a violation of the Principle of Least Astonishment to me...
    – user11946
    Aug 9, 2012 at 9:00
  • 2
    Weak/strong typing is ill-defined (as wiki also implies), please avoid it and be specific. I take it your definition bans implicit conversion, but not ad-hoc polymorphism? If so, consider Haskell, which has no implicit conversions but pretty well-executed (as in, works 99% of the time and can be comprehended by mortals) numeric polymorphism. And why would this be astonishing? It would be far more astonishing (not to say annoying) to me if I had to add a number of dots to every single instance of any operator, depending on the exact precision I wish.
    – user7043
    Aug 9, 2012 at 9:07
  • 2
    @JackManey I think to most newcomers it is way more surprising that 1/2 should equal 0 than it is if dividing two integers results in a double. After all integers aren't closed under division in maths either. Also as delnan points out, Haskell is an example of a strongly typed language in which / on two integers, doesn't produce an integer. And Python 3 is another.
    – sepp2k
    Aug 9, 2012 at 12:57
  • 1
    The Haxe language is strongly (albeit inferred) typed, and yet it has no integer division, only float. So there you go.
    – K.Steff
    Aug 9, 2012 at 13:19
2

In Squeak Smalltalk / on integers creates Fraction objects. So while this is not the same as float division, still (1/6)*6 returns 1.

1
  • In all Smalltalk-80 derivates (that is, nearly all Smalltalks). Amber is one of contemporary exceptions (which is understandable, being compiled to JavaScript).
    – herby
    Aug 9, 2012 at 16:15
2

Yes, I just checked my TI-99/4A's built in TI BASIC. As it treats all numeric expressions as floating point, the division operation is floating point as well.

 TI BASIC READY
>PRINT 1/6
  .1666666667

>
2

VB (VB.Net , VB6, VBA...)

The integer division operator is \

2

MATLAB. Numeric literals are doubles by default.

>> 1/6
ans =
    0.1667
2

Clojure does use fractions by default. It's not the same as 1.0/6.0, but you can convert to it with float or double when you need.

user=> (/ 1 6)
1/6
user=> (* (/ 1 6) 2)
1/3
user=> (pos? (/ 1 6)) ; Is 1/6 > 0?
true
user=> (float (/ 1 6))
0.16666667
1

Surprisingly, it seems to work properly in Windows PowerShell (version 3).

PS C:\> 1.0 / 6.0
0.166666666666667

PS C:\> 1/6
0.166666666666667

Also seems to work in Python 3 as sepp2k mentioned. The other two languages I have readily available on REPL, Scala and Ruby, both do integer division and yield 0.

0

The Rexx language always produces an arithmetically correct answer. For example: 5/2 = 2.5. Rexx is a great language that has not been utilized enough. In theory, when a compiler can't determine what do you want, its better to do the correct math, however, this may not be efficient. Rexx also provides the // operator.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.