2013-07-13 2 views
12

자바에서 약간의 포식자 - 먹이 시뮬레이션을 작성했습니다. 규칙이 사용하는 기술 매우 복잡하고 혼란 시스템에 끝날 경우에도 간단하다 : 기본 데이터 유형 Java가 결정적이지 않습니까?

  • 외부 시스템은 포함되지 않습니다
  • 외부 라이브러리에

    • 를 arithmetics과 결정은
    • 동시성은
    • 시스템과를 초기화 할 때 그래서 내가 생각

    현재 시간 또는 날짜없이 사용이 발생하지 동일한 결과를 출력해야하는 동일한 매개 변수가 있지만 그 이유는 궁금합니다.

    내 생각에 : 내 응용 프로그램은 Random을 사용합니다. 그러나이 테스트에서는 모든 값을 주어진 값으로 초기화하므로 이해할 때마다 동일한 순서로 동일한 출력을 실행해야합니다.

    나는 Set을 반복하고 있는데, Set이 반복되는 순서가 정의되어 있지 않음을 알고 있습니다. 그러나 같은 값으로 같은 순서로 채워지는 Set이 여러 번 실행될 때마다 다르게 동작해야하는 이유는 없습니다. 그거야?

    나는 많은 float을 사용하고 있습니다. 1 + 1 = 1.9999999999725 인 데이터 유형은 항상 저에게 의심 스럽지만, 저의 행동이 저에게 이상 할지라도 항상 이상해야합니다. 그렇지 않니?

    가비지 수집은 결정적이지 않지만, 소멸자에 의존하지 않는 한 안전해야합니다.

    위에서 언급했듯이 실제 사용 시간에 따라 동시성과 데이터 유형이 없습니다.

    간단한 예에서는 동작을 재현 할 수 없습니다. 그러나 제 코드를 살펴보면 예측할 수없는 것을 볼 수 없습니다. 그래서 틀린 위의 내 가정은 무엇입니까? 내가 누락 될 수있는 아이디어가 있습니까?

    은 여기 내 가정을 확인하기 위해 테스트 : 그것은 나를 위해 242455.25 항상 결과

    public static void main(String[] args) { 
        Random r = new Random(1); 
        Set<Float> s = new HashSet<Float>(); 
        for (int i = 0; i < 1000000; i++) { 
         s.add(r.nextFloat()); 
        } 
    
        float ret = 1; 
        int cnt = 0; 
        for (Float f : s) { 
         float multiply = 0.3f; 
         if (cnt++ % 2 == 0) { 
          multiply = 0.7f; 
         } 
         float f2 = (f * multiply); 
         ret += f2; 
        } 
    
        System.out.println(ret); 
    } 
    

    .

  • +1

    시간 기능? – Mysticial

    +1

    임의의 데이터를 초기화한다고 말하면 시드를 사용한다는 의미입니까? – tjameson

    +0

    재미있을 것 같습니다. 코드를 살펴 보시겠습니까? – kol

    답변

    20

    Java로 결정 성있는 프로그램을 작성할 수 있습니다. 가능한 비 결정론의 출처를 제거하면됩니다.

    실제 코드를 보지 않고 비 결정론을 일으킬 수있는 것이 무엇인지, 그리고 그 결정론의 구체적인 증거는 무엇인지 알기가 어렵습니다.

    잠재적으로 비 결정적 동작의 소스가 될 수있는 라이브러리 메소드에는 여러 가지가 있으며 사용 방법에 따라 다릅니다.

    예를 들어, Object.hashcode() (인스턴스에서 처음 호출 된) 값은 비 결정적입니다. 그리고 그것은 해싱을 사용하는 모든 라이브러리로 퍼집니다. 반복 할 때 HashSet 또는 HashMap의 요소가 반환되는 순서에 영향을 줄 수 있습니다 ... 요소 클래스가 hashcode()을 무시하지 않으면.

    임의 수 생성기는 결정적 일 수도 있고 그렇지 않을 수도 있습니다. 이들이 의사 난수이고 고정 된 시드로 초기화되는 경우, 각 시드에 의해 생성 된 일련의 수는 결정적입니다.

    부동 소수점 계산 이어야합니다. 산술 표현식에 대한 입력의 고정 된 세트의 경우, 결과는 항상 동일해야합니다. (I 부동 소수점 연산의 결정론이 JLS에 의해 보장되어 있는지 모르겠지만, 실제로 일어난 경우는 강력한 이상한 것입니다.로 ... 당신이 깨진 하드웨어에서 실행된다.)


    다음에 ...에 strictfp과 결정적이지 않습니다.

    JLS 15.4에 따르면 FP 엄격하지 않다 식에서

    "약간의 여유는 중간 결과를 나타 내기 위해 확장 된 지수 범위를 사용하여 구현 부여된다 순 효과를 대략 Float 값 세트 또는 double 값 세트를 독점적으로 사용하면 오버플로 또는 언더 플로우가 발생할 수있는 상황에서 계산에서 "정답"이 생성 될 수 있습니다. "

    이 정확히 구현이 아닌 FP-엄격한 표현에 얼마나 많은 "여유"말을하지 않습니다. 그러나, 그 여유가 비 결정적 행동을 허용하는 것으로 확장되지 않을 것이라고 생각했을 것입니다. 나는 특정 플랫폼의 JIT 컴파일러가 항상 같은 표현식에 상응하는 원시 코드를 생성하고 그 코드가 결정 론적이라고 생각했다. (하드웨어 자체에 비 결정적 부동 소수점이없는 한 비 결정론에 대한 이유는 없습니다.) 다른 비 결정론의 소스는 JIT 컴파일 및 해석 코드의 동작이 다를 수 있다는 것입니다. 그러나 솔직히, 나는 그것이 일어날 수 있도록하는 것이 "너트"라고 생각한다 ... 나는 우리가 그걸 들어봤을 것이라고 생각한다.

    FP가 엄격하지 않은 표현식 평가가 이론적으로 비 결정적 일 수 있지만 실제 상황에서 발생하는 확실한 증거가없는 한이를 할인해야한다고 생각합니다.

    (I 실제 비 결정론이 아니라 플랫폼의 차이에 대해서 이야기하고 있습니다.)

    +1

    부동 소수점 연산의 결정론은'strictfp'를 사용하지 않으면 보장되지 않습니다 -하지만 그것은 단지 여러 플랫폼에 걸쳐 있어야합니다. (+1) –

    +0

    'strctfp '가 없으면, 구현은 때로는 더 높은 정밀도를 사용하는 경우가 있습니다. –

    +0

    @PaulBellora - 예. 플랫폼 간 변수는 비 결정론과 같은 것이 아닙니다. 진정한 비 결정론이 있다면 fp 하드웨어에 결함이 있습니다. –

    10

    내가 설정 throu 반복하고있어, 나는이 설정이 반복되는 순서가 definied되지 않았 음을 알 수 있습니다. 하지만 동일한 값으로 동일한 순서로 채워진 Set이 여러 번 실행될 때마다 다른 모양으로 작동해야하는 이유는 없습니다. 그거야?

    수 있습니다. 구현은, 예를 들어 메모리 내의 오브젝트의 위치를, 기본이되는 해시 테이블의 키로서 자유롭게 사용할 수 있습니다. 가비지 콜렉션 실행시기에 따라 달라질 수 있습니다.

    +0

    @MichaelBulla - 어떤 JVM을 사용하고 있습니까? – tjameson

    +0

    @tjameson : 특정 JVM을 사용하지 않습니다. 이 질문은 일어날 수있는 일에 관한 것이지 일어나지 않을 수있는 것에 관한 것입니다. –

    +0

    "문제는 발생하지 않는 것 같습니다. OP를 통해 JVM에서 사용하는 기능을 알면 구현 노트를 찾아보고 이것이 구현에 의해 잠재적으로 발생하는지 확인할 수 있기를 바랍니다. – tjameson

    관련 문제