16

Reading over some older bits I've collected over the years, it appears that some early BASICs used a truncate for their INT function, but this was standardized on floor.

Any ideas why? Poking about I find many descriptions of the differences between floor/trunc/ceil, but no description that indicates why one might select one over another.

UPDATE: I have found examples of INT being truncate as late as 1978, in Benton Harbor BASIC, which explicitly claims to be a Dartmouth derivative.

Maury Markowitz
  • 19,803
  • 1
  • 47
  • 138
  • 2
    Mind to add examples for either? Also would it be possible to describe the difference you see between them (in context of BASIC)? Doing so might already reveal a very plausible reason :) – Raffzahn Oct 05 '23 at 23:30
  • 3
    In Atari/Commodore/HP/etc, INT(1.5) = 1, INT(-1.5) = -2. That seems like not what the user would expect. Early Dartmouth, up to 4 IIRC, INT(-1.5)=-1, which seems like what you want. – Maury Markowitz Oct 05 '23 at 23:39
  • FWIW, the Algol 60 Revised Report defines the standard function entier(E) as returning 'the largest integer which is not greater than E', i.e., it's floor. – dave Oct 05 '23 at 23:44
  • Not familiar with Algol really, but it also has a INTEGER, which appears to truncate. – Maury Markowitz Oct 05 '23 at 23:48
  • Point was to add this information to the question, improving it. – Raffzahn Oct 05 '23 at 23:54
  • The language doesn't (entier is the only standard transfer function) but an implementation might. – dave Oct 05 '23 at 23:54
  • Is this related to whether your language defines a 'modulo' versus 'remainder' function or operator? – dave Oct 06 '23 at 00:01
  • 3
    I gave up a long time ago wondering why different dialects or languages implemented functions slightly differently. Just had to be careful. – Jon Custer Oct 06 '23 at 00:23
  • @JonCuster there isn't as much variation as one may assume from the question - all BASIC I can remember use the same interpretation of flooring. – Raffzahn Oct 06 '23 at 01:00
  • Again FWIW, in the interest of a survey of contemporary languages, FORTRAN II seems to say it truncates towards zero when assigning a REAL value to an INTEGER, but the manual neglects to show an example with a negative value. FORTRAN IV uses the word 'truncate' but again fails to give a negative example. – dave Oct 06 '23 at 02:17
  • FWIW, BBC BASIC also uses floor.  The manual says: “This converts a number with a decimal part to a whole number.  This function always returns a whole number smaller than the number supplied.  Thus INT(23.789) gives 23 whereas INT(-13.3) returns -14.” (my emphasis) – gidds Oct 06 '23 at 13:00
  • I couldn't remember how it worked on the HP 2000 I learned BASIC on, so I looked it up: The INT function is a numeric-valued function which returns the integer part of the numeric expression. The integer part of a number is that integer less than or equal to the number. For example, INT(3.5) = 3 but INT( -3.5) = -4. I don't think I ever used it on negative numbers. That quoted bit seems self-contradictory in its definition of "integer part". – Mark Ransom Oct 06 '23 at 16:19
  • @gidds: It's too bad people aren't taught consistent set of distinct meanings for "larger", versus "higher", or "smaller" versus "lower". Describing -1.5 as being both larger and lower than -1.2 would facilitate a lot of discussions regarding integer arithmetic. – supercat Oct 06 '23 at 17:33
  • 2
    If you see a number as being made of (integer part) + (decimal part) and call truncation the removal of the (decimal part), it makes sense. E.g. 3.2 = (3)+(0.2); -3.2=(-4)+(0.8). – Andrew Morton Oct 06 '23 at 17:49
  • 1
    @gidds - The BBC BASIC definition could have used some proof-reading (by them, not you: "returns a whole number smaller than the number supplied". OK, so clearly INT(9) can return 8 or 7 or 6 or ... but it definitely cannot return 9. – dave Oct 07 '23 at 12:36
  • @AndrewMorton - but just as readily, -3.2 = (integer part) + (decimal part) = (-3) + (-0.2). – dave Oct 07 '23 at 12:44
  • @another-dave I should have written a non-negative decimal part. – Andrew Morton Oct 07 '23 at 14:07
  • @AndrewMorton I think most people's definition of "integer part" will be the part prior to the decimal point. Your definition is logically defensible, but I don't think many people expect "-4" to be the integer part of "-3.". It's especially confusing that -3.2 and -3.0 will convert to integer differently. – Mark Ransom Oct 09 '23 at 16:11

1 Answers1

31

It Has (Almost) Always Been Floor

Since at least 1966, with Dartmouth BASIC V3, the behaviour of INT is defined as as delivering an integer not greater than X - which otherwise may be called FLOOR. This is consistent with all BASIC I know.

Why? Because Enhanced Usability

Truncate can only be used to relieve float numbers from their fractions. To use it for rounding, sign handling needs to be implemented differently for positive and negative numbers, requiring a 4-line construct:

100 If I < 0 THEN 130
110 I = INT(I+0.5)
120 GOTO 140
130 I = INT(I-0,5)
140 ...

In contrast, a Floor implementation works independently of the sign always in the same 'direction', enabling easy use in single statement of

I = INT(I+0.5)

Same would have been true for use of Ceiling(*1), except Floor also works like Truncate for all positive numbers. Something easy to understand for beginners (students) thus a perfect compromise for a teaching language. One function good to show two very common use cases.


Some Archaeology

A good starting point in search for default behaviour of BASIC are always the ECMA standards 55 for Minimal BASIC (1978) and 110 for 'full' BASIC (1985). For an item as basic as INT ECMA-55 notes:

enter image description here

(ECMA-55 section 9.4 on page 12)

European ECMA-55 standard which is essentially the same as US ANSI X3.60-1978 standard, which in turn is based on SBASIC, an intermediate step between Dartmouth V6 and V7 made in 1976. Since it was implemented as preprocessor for V6 it can be assumed that Dartmouth BASIC V6 created in 1969, published in 1971 as well used INT with the same definition.

Looking into the 1968 V4 documentation shows the same behaviour

enter image description here

(Page 42 of the BASIC Version 4 manual)

Going back to V2 of 1964 shows different:

enter image description here

(Page 39 of the BASIC Version 2 manual)

This quite complex explanation already shows why Truncate isn't as great for a beginners' language as Floor.

The change from 'Truncate' to 'Floor' must have happened before V4 and considerable before it gathered widespread use. Wikipedia notes that V3 was the first to feature that change. V3 was finished in 1966, a mere two years after the very first BASIC (*2). The early on change supports why all later BASIC employ the same workings. No matter whether 1975 Prime BASIC or 1991 Visual BASIC.


*1 - At that point it may become obvious that the function group to look at isn't the mentioned triple of Truncate/Floor/Ceiling but a quadruple including ROUNDING as well.

*2 - I'm not sure if any other BASIC already existed in 1966.

Toby Speight
  • 1,611
  • 14
  • 31
Raffzahn
  • 222,541
  • 22
  • 631
  • 918
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed. – Chenmunka Oct 11 '23 at 08:15