1 / 37

부동소수점 (FLP)

부동소수점 (FLP). 사이버보안학과 김현성. 제안. FLP00-C 부동소수점 수의 제한을 이해하라 FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 FLP03-C 부동소수점 에러를 발견하고 처리하라. 규칙. FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라

prem
Download Presentation

부동소수점 (FLP)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 부동소수점(FLP) 사이버보안학과김현성

  2. 제안 • FLP00-C 부동소수점 수의 제한을 이해하라 • FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 • FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 • FLP03-C 부동소수점 에러를 발견하고 처리하라

  3. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  4. 제안 • FLP00-C 부동소수점 수의 제한을 이해하라 • FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 • FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 • FLP03-C 부동소수점 에러를 발견하고 처리하라

  5. 부동소수점 수의 제한을 이해하라 부동소수점 14e2 123e-3 14x102=1400 123x10-3=0.123 • 실수를 부호, 지수, 소수의 세 부분으로 구분하여 표현 • 4바이트를 사용하는 부동 소수점 형식

  6. 부동소수점 수의 제한을 이해하라 부동소수점 • 어떤 시스템으로 구현되었든지 고정된 정밀도를 가짐 • 반올림과 관련된 에러 유발 가능성 있음 • 시스템에 따라 정밀도와 표현 가능한 값의 범위가 다름 => 컴퓨터는 유한한 개수의 숫자 표현 가능

  7. 부동소수점 수의 제한을 이해하라 FLP00-C 코드 예 #include <stdio.h> int main (void) { float f = 1.0f / 3.0f; printf(“Float is %.50f\n”, f); return 0; } => 0.33333333333333333333333333 => Linux GCC 0.33333334326744079843750000 XP Visual C++ 9.0 0.33333334326744080000000000

  8. 제안 • FLP00-C 부동소수점 수의 제한을 이해하라 • FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 • FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 • FLP03-C 부동소수점 에러를 발견하고 처리하라

  9. 부동소수점 표현식을 재배치할 때 주의하라 FLP01-C 코드 예 x *= y * z; z = x; z = x * (1.0 + y); y = x * 0.2; double x, y, z; /* ... */ x = (x * y) * z; z = (x – y) + y; z = x + x * y; y = x / 5.0; => 범위 한계 및 정밀도 한계로 인해서 문제 발생됨(Round off)

  10. 제안 • FLP00-C 부동소수점 수의 제한을 이해하라 • FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 • FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 • FLP03-C 부동소수점 에러를 발견하고 처리하라

  11. 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 FLP02-C 부적절한코드 예 => mean is 10.1 => mean is 10.099999 64Linux with GCC 4.1 #include<stdio.h> float mean(float array[], int size) { float total = 0.0; int i; for (i=0; i<size; i++){ total += array[i]; printf(“array[%d] = %f and total is %f\n”, i, array[i], total); } if (size != 0) return total / size; else return 0.0; } enum {array_size = 10}; float array_value = 10.1; int main(void) { float array[array_size]; float avg; int i; for (i=0; i<array_size; i++) array[i] = array_value; avg = mean(array, array_size); printf(“mean is %f\n, avg); if (avg == array[0]) { printf(“array[0] is the mean\n”); } else { printf(“array[0] is not the mean\n”); } return 0; }

  12. 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 FLP02-C 해결방법 #include<stdio.h> float mean(int array[], int size) { int total = 0; int i; for (i=0; i<size; i++){ total += array[i]; printf(“array[%d]=%f and total is %f\n”, i, array[i]/100.0, total/100.0); } if (size != 0) return total / size; else return 0.0; } enum {array_size = 10}; int array_value = 1010; int main(void) { int array[array_size]; float avg; int i; for (i=0; i<array_size; i++) array[i] = array_value; avg = mean(array, array_size); printf(“mean is %f\n, avg/100.0); if (avg == array[0]) { printf(“array[0] is the mean\n”); } else { printf(“array[0] is not the mean\n”); } return 0; }

  13. 제안 • FLP00-C 부동소수점 수의 제한을 이해하라 • FLP01-C 부동소수점 표현식을 재배치할 때 주의하라 • FLP02-C 정확한 계산이 필요할 때는 부동소수점 수를 배제할 수 있는지 고려하라 • FLP03-C 부동소수점 에러를 발견하고 처리하라

  14. 부동소수점 에러를 발견하고 처리하라 FLP03-C 부적절한코드 예 voidfpOper_noErrorChekin(void) { /* ... */ double a = 1e-40, b, c = 0.1; float x = 0, y; /* 부정확하며 언더플로우가 발생 */ y = a; /* 0으로 나누는 에러 */ b = y / x; /* 부정확함(정밀도를 잃어버림) */ c = sin(30) * a; /* ... */ }

  15. 부동소수점 에러를 발견하고 처리하라 pragma • 컴파일러에 직접 명령을 내리기 위한 지시자( #pragma STDC 로 시작 ) • 종류 #pragma once : 해당명령 한번만 컴파일 #pragma warning : 특정 경고 에러 띄우지 않음 #pragma comment : 라이브러리를 인클루드할 때 많이 사용 #pragma pack : 메모리 공간 최적화

  16. 부동소수점 에러를 발견하고 처리하라 fenv.h • 부동소수점 환경을 제어하기 위한 C99표준함수

  17. 부동소수점 에러를 발견하고 처리하라 FLP03-C 해결방법 #include <fenv.h> /* 부동소수점 에러 처리 표준 함수 */ #pragma STDC FENV_ACCESS ON voidfpOper_fenv(void) { double a = 1e-40, b, c = 0.1; float x = 0, y; int fpeRaised; /* ... */ feclearexcept(FE_ALL_EXCEPT); /* a를 y에 저장하면 값이 부정확해지고 언더블로우 발생 */ y = a; fpeRaised = fetestexcept(FE_ALL_EXCEPT); /* fpeRaised는FE_INEXACT와 FE_UNDERFLOW가짐 */ feclearexcept(FE_ALL_EXCEPT); /* 0으로 나누는 연산 */ b = y / x; fpeRaised = fetestexcept(FE_ALL_EXCEPT); /* fpeRaised는FE_DIVBYZERO가짐 */ feclearexcept(FE_ALL_EXCEPT); c = sin(30) * a; fpeRaised = fetestexcept(FE_ALL_EXCEPT); /* fpeRaised는FE_INEXACT가짐 */ feclearexcept(FE_ALL_EXCEPT); /* ... */ }

  18. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  19. 부동소수점 변수를 루프 카운터로 사용하지 마라 FLP30-C 부적절한코드 예 for(float x = 0.1f; x <= 1.0f; x+= 0.1f) { /* ... */ } => for 루프 10회 실행 => IA-32머신 Window XP, Visual C++ 2005 v8.0 -> 9회 실행

  20. 부동소수점 변수를 루프 카운터로 사용하지 마라 FLP30-C 해결방법 for(size_t i = 1; i <= 10; i += 1) { float x = i/10.0f; /* ... */ }

  21. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  22. 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 복소수로호출하면 안되는 함수

  23. 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 FLP31-C 부적절한코드 예 double complex c = 2.0 + 4.0 * I; /* ... */ double complex result = log2(c); => log2는 실수값 만을 허용하는 타입이므로 정의되지 않은 동작 초래

  24. 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 FLP31-C 해결방법 double complex c = 2.0 + 4.0 * I; /* ... */ double complex result = log2(creal(c)); 복소수의 실수부 계산

  25. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  26. 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 도메인체크 • 수학 함수에 전달되는 인자 값이 함수 정의 시 지정된 도메인 안에 있음을 보장해 예방 if( /* 인자 값이 도메인 에러를 유발할 수 있음 */) { /* 도메인 에러 처리 */ } else { /* 계산수행 */ }

  27. 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 범위체크

  28. 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 범위체크

  29. 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 FLP32-C 부적절한코드 예 doublex; double result; /* x 초기화 */ result = sqrt(x); => x의 제곱근 구함 => x가 음수인 경우 에러 발생

  30. 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 FLP32-C 해결방법 doublex; double result; /* x 초기화 */ if (isless(x,0)) /* 범위 에러 처리 */ else result = sqrt(x);

  31. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  32. 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 FLP33-C 부적절한코드 예 short a = 533; int b = 6789; long c = 466438237; float d = a / 7; double e = b / 30; double f = c * 789; => d=76.0 e=226.0 f=368019768993 => d, e, f가 부정확하게 초기화되어 값의 일부가 정수 근처에서 잘리거나 오버플로우 발생 가능

  33. 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 FLP33-C 해결방법 short a = 533; int b = 6789; long c = 466438237; float d = a / 7.0; double e = b / 30.0; double f = double(c) * 789;

  34. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

  35. 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라 FLP34-C 부적절한코드 예 float f1; int i1; /* f1 초기화 */ i1 = f1; => f1의정수 부분이 INT_MAX보다 큰 경우 정의되지 않음

  36. 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라 FLP34-C 해결방법 float f1; int i1; /* f1 초기화 */ if ( f1 > (float) INT_MAX || f1 < (float) INT_MIN) { else { i1 = f1; }

  37. 규칙 • FLP30-C 부동소수점 변수를 루프 카운터로 사용하지 마라 • FLP31-C 함수에 복소수를 사용하면서 실제 값을 얻을 거라 기대하지 마라 • FLP32-C 수학 함수에서 도메인 에러나 영역 에러를 찾고 예방하라 • FLP33-C 부동소수점 연산용 정수는 먼저 부동소수점으로 바꿔라 • FLP34-C 부동소수점 변환이 새로운 타입의 범위 안에 들어가는지 확인하라

More Related