1/6이 1.0 / 6.0과 동일하게 동작하는 프로그래밍 언어가 있습니까?


11

며칠 전에 C ++로 프로그래밍하는 동안이 실수를 저질렀습니다 (내역이 있습니다!). 내 코드의 한 부분에서 1/6이 있었고 0.16666666666이 될 것으로 기대했습니다. 모두 알다시피 결과는 0입니다-C, C ++, Java, Python, 모두 동일하게 동작합니다.

내 Facebook 페이지에 게시하면 이제 1/6와 같은 동작을 하는 프로그래밍 언어가 있는지에 대한 토론이 있습니다 1.0/6.0.


5
하스켈. 1/6 = 0.16666666666666666
t123

PowerShell은 0.166666666666667을 생성하는데 1은 정수이므로 놀랍습니다. 예상 한 가치를 창출하는 다른 .NET 언어가 있습니다.
JohnL

이론 상으로는 그것들의 수에는 제한이 없습니다. 여기 다른 것이 있습니다 : Rebol 과 Orca, Red 등과 같은 파생물들. >> 1 / 6->== 0.166666666666667
이즈 카타

루아는 이것을한다. 단일 숫자 유형 만 있으며 일반적으로 C의 double과 동일합니다.
Machado

Clojure 1/6에서 실제로 1/6 (분수 타입)이며, Double1.66666입니다
kaoD

답변:


17

모두 파스칼을 잊었습니까?

1/6수율 0.1666666...(지원되는 모든 정밀도).

1 div 6 수확량 0

C 규칙이 실수인지 여부는 논쟁의 여지가 있습니다. 피연산자가 동일한 유형 인 거의 모든 C의 산술 연산자는 동일한 유형의 결과를 생성합니다. 일관성에 대해 말해야 할 것이 있습니다.

또한 C는 주로 시스템 수준 코드를 대상으로하기 때문에 대부분의 C 프로그램은 부동 소수점을 전혀 사용하지 않습니다. 한 번에 실수로 부동 소수점 코드를 필요하지 않은 프로그램에 부동 소수점 코드를 추가하면 심각한 문제가 될 수 있습니다. 작은 임베디드 시스템의 경우에도 여전히 그렇습니다.이 역시 C의 주요 목표입니다.

대부분의 C 프로그램에서 정수 나누기를 자르는 것은 아마도 어쨌든 원하는 것입니다.

1 / 6C에서 부동 소수점 결과가 나오면 다음을 수행하십시오.

  • 언어가 일치하지 않을 것입니다.
  • 이 표준은 임의의 선택이 될해야 하는 결과에 사용할 부동 소수점 유형 ( double자연 선택처럼 보일 수 있지만, 당신은의 여분의 정밀도를 선호 할 수도 있습니다 long double)
  • 언어는 여전히 정수 나누기 연산이 있어야합니다. 부동 소수점 덧셈을 수행 한 다음 절단하는 것만으로는 충분하지 않을 수 있습니다.

C 는 두 종류의 나누기에 별도의 연산자를 제공 할 수 있지만 위의 두 번째 점은 여전히 ​​적용됩니다. 세 가지 부동 소수점 형식 중 어느 것이 결과에 사용됩니까? 그리고 필요한 경우 부동 소수점 나누기를 쉽게 얻을 수 있기 때문에 (한 피연산자 중 하나 또는 둘 모두에 대해 부동 소수점 상수를 사용하거나 피연산자 중 하나 또는 둘 모두를 부동 소수점 유형으로 캐스팅), 분명히 그렇지 않았습니다. ' 그 점을 중요하게 생각했습니다.

C 매뉴얼의 1974 버전 (K & R의 첫 번째 판이 출판되기 4 년 전)에서 Ritchie는 혼란을 언급하지도 않았습니다.

이진 / 연산자는 나눗셈을 나타냅니다. 곱셈과 동일한 유형 고려 사항이 적용됩니다.

두 피연산자가 모두 유형 int이거나 char이면 결과는 유형 int입니다.

예, 일부 C 프로그래머, 특히 초보자에게는 혼란의 원인이지만 C는 초보자에게 친숙하지 않습니다.


5
파스칼. C가 잘못되기 직전에 세부 정보 얻기.
Mason Wheeler

그리고 Algol은 그 후임자 (C와 Pascal의 수 모두)보다 개선되었습니다.
AProgrammer

파스칼 (Pascal) – 세부 사항을 정확하게
Martin Beckett

1
나는 원래 썼다 1.666666.... 필자의 핑계는 내가 작성한 파스칼 테스트 프로그램이 인쇄되었다는 것입니다.1.6666666666666667E-0001
Keith Thompson

16

실제로이 동작은 Python 3에서 변경되었으며 이제는 예상대로 작동합니다 ( //이제 정수 나누기에 사용됨).


감사. 다른 프로그래밍 언어가 있습니까? 기본 가족?
Pouya

1
@Pouya :이 동작은 Pascal 제품군의 표준입니다. /항상 부동 소수점 값을 생성하며 div정수 나누기에 별도의 연산자 ( )가 사용됩니다.
메이슨 휠러

13

저명한 언어 중 JavaScript. 1.0 / 6.0 = 1/6 = 0.16666666666666666.

나는 이것이 놀라운 것으로 보지 않습니다. 경험상 언어가 정수와 부동 소수점 숫자 유형을 구별하는 경우 두 정수를 나누면 float 대신 잘린 정수가 생성됩니다. 그렇지 않으면 대부분 부동 소수점 연산으로 설정됩니다. 이것은 프로그래머 측에서 예상되는 동작이어야합니다.

이미 언급 한 별도의 정수 나누기 연산자 또는 암시 적 유형 캐스팅과 같이 여기에서도 사용할 수있는 추가 사항이 있음을 명심하십시오.


6
이것은 "거의 법칙"이 아닙니다. C의 규칙이며 C의 실수를 맹목적으로 복사 한 소수의 언어입니다.
메이슨 휠러

4
@MasonWheeler : FORTRAN이 "맹목적으로 C의 실수를 복사 했습니까?" 개인적으로 잘 디자인 된 언어는 잘린 나눗셈 대 정수 수량의 근사 나누기 (값과 참조 평등의 경우 btw)에 별도의 연산자를 사용해야한다고 생각하지만 FORTRAN 시대의 디자인 결정은 합리적이었습니다. 그렇다고 FORTRAN이 1950 년대에했던 방식대로 모든 언어가해야하는 것은 아닙니다.
supercat

3
저급 언어는 이러한 구분을해야합니다. 높은 수준의 / 동적 언어는 종종 언어가없는 것이 좋습니다. 디자인 트레이드 오프입니다. JS에 하나의 큰 벙어리 숫자 생성자 / 유형이 있다는 것에 감사하지만, 엄격한 유형 제어없이 고성능 3D 엔진을 작성하려고 할 때 JS가 부족하다고 생각할 것입니다. JS는 다른 언어와 겹치는 유틸리티를 가지고 있을지도 모르지만, 크롬에 가까운 고성능 유형의 글을 작성하기 위해 아무도 그것을 고려하지 않을 것이라고 생각합니다.
Erik Reppen

2
프로그래밍 이외의 수학에서는 나누기의 정수 전용 규칙을 고려합니다.
Erik Reppen

5
@MasonWheeler : 프로그래밍은 순수한 수학이 아닙니다. 수학적으로 1/6은 합리적인 숫자이며 이진 부동 소수점 숫자로 정확하게 표현할 수 없습니다. 정확한 표현은 분자의 6 배 분모를 갖는 비율입니다.
kevin cline

7

((1/6)*6)결과는 0이 아닌 1 이되는 많은 언어가 있습니다. 예를 들어 PL / SQL, 많은 BASIC 방언, Lua.

우연히도, 모든 언어에서 1/6은 .166666667 또는 0.16666666666667 또는 이와 유사한 결과를 낳습니다. 그 작은 차이점을 없애기 위해 ((1/6) * 6) == 1 변형을 선택했습니다.


7
그것은 질문이 아닙니다.
Roc Martí

20
우연히도, 모든 언어에서 1/6은 .166666667 또는 0.16666666666667 또는 이와 유사한 결과를 낳습니다. ((1/6)*6)==1그 작은 차이를 없애기 위해 변형을 선택 했지만 일부 사람들의 수학 기술을 과대 평가 한 것처럼 보입니다.
user281377

1
@ RocMartí 그렇습니다, 정말 ...
MattDavey

1
(1.0 / 6.0) * 6이 정확히 1과 같다는 것을보고 놀랐습니다! (1.0 / 6.0) 결과의 반올림은 작은 차이로 이어집니다. (무한 정밀도로 기본 설정되는 몇 가지 언어가 있지만)
Sjoerd

1
@ Sjoerd : 실제로 그것이 정확하다는 것은 너무 놀랍지 않습니다. 십진수로 1/11 * 11의 시나리오를 고려하십시오. 모든 값은 5 개의 유효 숫자로 정확합니다. 1/11의 값은 9.0909 * 10 ^ -2입니다. 11을 곱하면 반올림하기 전에 99.9999 * 10 / -2가됩니다. 유효 숫자 5 자리로 반올림하면 결과는 1.0000 * 10 ^ 0입니다. 핵심은 1/6의 가수가 "... 0101010101 ..."이라는 것입니다. 표현의 마지막 비트가 "1"인 경우 6을 곱하고 반올림하면 1이됩니다. 마지막 비트가 0이면 그렇지 않습니다.
supercat

3

Haskell은 1/6과 1.0 / 6.0을 동일하게 0.16666666666666666으로 취급합니다. 또한 1 / 6.0 및 1.0 / 6을 동일한 값으로 렌더링합니다.

이것은 Haskell의 기본 숫자 유형이 다른 언어와 동일하지 않기 때문입니다. 진정한 정수 나누기는 다소 복잡합니다.


2

펄은 그렇습니다. 원 라이너

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

결과는 다음과 같습니다.

0.166666666666667

나는 PHP가 같은 방식으로 작동한다고 생각합니다.

추가하기 위해 편집 : 나는 또한 필요한 (충분하지는 않지만) 조건 1/6 == 1.0/6.0이 문제의 언어를 약하게 입력 하는 것이라고 생각합니다 .


도대체 약한 타이핑이 필요한 이유는 무엇입니까? 두 인수가 모두 정수인 경우 / to (또한) float float 나누기를 정의하십시오.

1
@delnan - en.wikipedia.org/wiki/Weak_typing 나는있는 강력한 형식의 언어를 가질 수있을 가정 /자동으로 인자의 종류에 따라 오버로드를, 그러나 그것은을 위반하는 것 같아 원리 최소 깜짝의 에 나 ...

2
약한 / 강력한 타이핑은 잘 정의되어 있지 않습니다 (위키도 알 수 있듯이). 나는 당신의 정의가 암묵적 변환을 금지하지만 임시 다형성은 금지한다고 생각합니까? 그렇다면 암묵적인 변환은 없지만 99 % 작동하며 필사자들이 이해할 수있는 수치 적 다형성 인 Haskell을 고려하십시오. 왜 이것이 놀라운 일입니까? 내가 원하는 정확한 정밀도에 따라 어떤 연산자의 모든 단일 인스턴스에 여러 개의 점을 추가해야한다면 그것은 훨씬 더 놀라운 일입니다.

2
@JackManey 나는 대부분의 새로운 이민자들에게 두 정수를 나눠서 두 배가되는 경우보다 1/2이 0과 같아야한다는 것이 더 놀랍습니다. 모든 정수는 수학에서 나눗셈으로 닫히지 않습니다. 또한 delnan이 지적한 것처럼 Haskell은 두 개의 정수에서 /가 정수를 생성하지 않는 강력한 형식의 언어의 예입니다. 그리고 파이썬 3은 또 다른 것입니다.
sepp2k

1
Haxe 언어는 강력하지만 (유추되지만) 유형이 정해져 있지만 정수 나누기가없고 float 만 있습니다. 그래서 당신은 간다.
K.Steff

2

/정수 에서 스 쿼크 스몰 토크 에서는 분수 객체를 만듭니다. 따라서 이것은 float 나누기와 같지 않지만 여전히 (1/6)*61을 반환합니다.


모든 Smalltalk-80에서 파생됩니다 (즉, 거의 모든 Smalltalks). 앰버는 현대의 예외 중 하나입니다 (이해할 수 있고 JavaScript로 컴파일 됨).
herby



2

MATLAB. 숫자 리터럴은 기본적으로 두 배입니다.

>> 1/6
ans =
    0.1667

2

Clojure는 기본적으로 분수를 사용합니다. 1.0 / 6.0과 동일하지 않지만 필요할 때 float또는 double필요할 때 변환 할 수 있습니다 .

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

놀랍게도 Windows PowerShell (버전 3) 에서는 제대로 작동하는 것 같습니다 .

PS C:\> 1.0 / 6.0
0.166666666666667

PS C:\> 1/6
0.166666666666667

sepp2k가 언급했듯이 Python 3에서도 작동하는 것 같습니다. REPL, Scala 및 Ruby에서 쉽게 사용할 수있는 다른 두 언어는 정수 나누기와 0을 산출합니다.


0

Rexx 언어는 항상 산술적으로 정답을 만듭니다. 예를 들어 5/2 = 2.5입니다. Rexx는 충분히 활용되지 않은 훌륭한 언어입니다. 이론적으로 컴파일러가 원하는 것을 결정할 수 없으면 올바른 수학을 수행하는 것이 더 좋지만 효율적이지 않을 수 있습니다. Rexx는 // 연산자도 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.