레이블이 연산자인 게시물을 표시합니다. 모든 게시물 표시
레이블이 연산자인 게시물을 표시합니다. 모든 게시물 표시

2015년 7월 17일 금요일

맥시마(maxima)의 산술 연산

 산술 연산은 타 프로그래밍 언어에서도  거의 공통적으로 쓰이는 기호가 맥시마에서도 사용된다. 맥시마는 수를 표현하는 방식에서 ‘기호 형식’과 ‘수치 형식’이 있으며 (numer 라는 내부 변수에 의해서 지정됨.) 기본적으로 초기에는 기호 형식으로 동작한다. 이 두 가지 형식의 차이점을 예를 들어서 설명하면 다음과 같다. 기호모드에서는 1/11 이라는 분수를 그냥 분수의 형태로 저장하며 사실 이 수는 이 형태가 정확한 표현인 것이다. 그러나 수치모드에서는 이 숫자를 입력하면 0.090909090909091 와 같이 소수형식으로 표현되며 엄밀히 얘기하면 이 수는 1/11 의 근사값이다. 다음 [표 1]에 Maxima에서 쓰이는 산술연산기호를 정리하였다.
[표 1] 맥시마의 산술 연산자
기호
작업
비고
+
덧셈
※내부 변수 numer 의 진리값에 따라 표시 결과가 다름
-
뺄셈
*
곱셈
/
나눗셈
^
거듭 제곱


똑같은 명령어라도 수치 형식인 경우는 결과가 달라진다. 내부 변수와 변수에 값을 지정하는 방법은 뒤에서 다루어지므로 여기에서는 그냥 결과만 확인하자.


여기에서 numer:true 명령은 numer라는 내부 변수에 true라는 값을 대입하는 것이다. 맥시마는 특이하게 대입 연산자가 콜론(:)이다.

 만약 현재 모드를 바꾸지 않고 특정 수식의 실수 값을 확인하고 싶으면 float()함수를 사용하거나 표현식 뒤에 ‘, numer’라고 추가입력하면 된다.


 산술연산 기호를 이용하면 Maxima에는 대수식이나 방정식과 같은 것들도 쉽게 표현할 수 있다. 만약 x2+2x+1,1/(y2+1)이라는 대수식을 입력하려면 아래와 같이 하면 된다.


 연습 문제로 다음과 같은 식을 입력하고 확인해 보자.


2015년 6월 17일 수요일

싸이랩(scialb)의 연산자와 기정의 상수들

기본적인 연산자

 다음 표에 기본적인 Scilab연산자를 정리하였다. Scilab의 기본 객체는 ‘행렬’이므로 피연산자도 일반적으로 ‘행렬’이다.

[표 1] 기본 연산자
연산자
기능
+
덧셈(이항연산자), +부호(단항연산자)
-
뺄셈(이항연산자), -부호(단항연산자)
*
곱셈
.*
요소간 곱셈
.*.
Kronercker 곱셈. kron(A,B)와 동일
/
나눗셈
\
역나눗셈 (즉 a\b 는 b를 a로 나눈다)
./
요소간 나눗셈
.\
요소간 역나눗셈
./.
Kronecker 나눗셈
.\.
Kronecker 역나눗셈
^ 또는 **
거듭 제곱
.^
요소간 거듭 제곱
‘(작은따옴표)
복소 전치 행렬
.’(점작은따옴표)
단순 전치 행렬

이 표에서 보면 요소간 연산자가 있는데 이것은 행렬 간 연산에서 같은 요소끼리의 연산을 수행한다. 예를 들어서 두 행렬 A, B에 대해서 A*B는 보통의 행렬곱으로 A의 열수와 B의 행수가 같아야 성랍하지만 A.*B 는 같은 위치의 요소끼리 곱셈을 수행하므로 A와 B의 크기가 같아서 수행된다. 예제는 행렬에 대해서 알아볼 때 들겠다.

 대입문을 작성할 때 tuple을 사용하여 한 번에 여러 변수를 지정하는 것이 가능하다. tuple 은 괄호 ( ) 를 사용하는데 각각의 요소는 반드시 comma (,)로 구분해야 한다. 이 기능을 사용하면 변수들을 서로 swap하는 데도 간결하게 사용할 수 있다.(이 기능은 python과 흡사하다.)

 아래에서 첫 번째 예가 변수 u, v 그리고 w 를 동시에 생성하는 것이다. 좌변에는 [ ... ] 를 우변에서 tuple을 지정할 때는 ( ... ) 를 사용했음에 유의해야 한다, 두 번째 예는 u와 v의 값을 서로 맞바꾸는 것이다.

내부 상수들

 다음 표에 미리 정의되어 사용되는 내부 상수들을 정리하였다. 이 변수들은 모두 %로 시작하며 사용자가 덮어 쓸 수 없다.(즉, 재정의될 수 없다.)

[표 2] Scilab의 기정의된 내부 상수들
변수명
의미
%i
허수 ()
%e
자연상수 (2.718281…)
%pi
원주율 (3.142592…)
%eps
표현가능한 가장 작은 수(약 2.2e-16)
%inf
무한대
%nan
not a number
%t or %T
(논리적) 참
%f or %F
(논리적) 거짓
%s
다항식 s=poly(0,’s’)
%z
다항식 s=poly(0,’z’)
%io
표준 I/O
Scilab의 식별자에서 ‘%’를 사용할 수 있는데 맨 첫자로만 사용가능하다. 따라서 위의 상수들은 모두 특정 값이 저장되어 있고 변경할 수 없는 변수와 같이 취급된다.


2015년 5월 26일 화요일

C/C++ 연산자 연습 문제

  1. C/C++의 연산자의 종류에 대해서 기술하라.
  2. C/C++의 연산자들 중 단항 연산자를 모두 기술하라.
  3. 증감 연산자 ++, --가 변수에 붙는 방향에 따라 동작이 어떻게 달라지는지 기술하라.
  4. 하나의 정수를 입력받아서 짝수이면 "even number!" , 홀수이면 "odd number!"라고 화면에 표시하는 프로그램을 작성하라. (조건 연산자를 이용할 것)
  5. 어떤 int형 정수를 입력받아서 그 수의 절대값을 화면에 출력해 주는 프로그램을 작성하라.
  6. 세 개의 int형 정수를 입력받아서 그 중 가장 큰 수를 화면에 출력해 주는 프로그램을 작성하라.
  7. unsigned char형 변수값을 이진수로 표기해주는 프로그램을 작성하라.
  8. 두개의 복소수를 입력받아서 곱셈 결과를 출력하는 프로그램을 작성하라.
  9. 2차 방정식 x2+ax+b=0 의 계수 a, b값(double형)을 읽어들여서 두 근을 표시하는 프로그램을 작성하라.
  10. 변수 ucA의 상위 니블을 반전시키는 코드를 작성하라.
  11. 변수 ucB의 b2가 0이라면 화면에 “LED off”, 1이라면 “LED on”이라고 출력하는 프로그램을 작성하라.
  12. 변수 ucC의 초기값을 0x0F이다. 이 변수값 전체가 주기적으로 반전되는 프로그램을 작성하라. (단 시간을 지연시키는 함수는 _delay_ms(unsigned shot usN )이라고 가정하고 usN에는 밀리세컨드 숫자를 입력한다고 하자.)

C/C++ 연산자의 우선 순위와 결합 방향

연산자 우선 순위

 한 수식에 여러 개의 연산자를 사용하는 경우에 연산자들의 우선순위를 고려하지 않을 수 없다. 연산자 우선순위를 정리하면 다음과 같다.
  1. 괄호, 배열, 구조체, 공용체멤버를 나타내는 지시자 (), [], ->, . 은 우선순위가 가장 높다.
  2. 한 개의 피연산자를 갖는 단항연산자(!, ++, -- 등)이 그 다음으로 우선순위가 높다.
  3. 그 다음은 산술 연산자 (+, - *, /, %)이다.
  4. 쉬프트연산자와 비교연산자는 비트연산자보다 연산순위가 높다.
  5. 맨 하위에 대입연산자와 콤마(,)연산자가 있다.

[표 1] 연산자 우선 순위와 결합 방향
순위
연산자
결합 방향
1
( ) [ ] -> .
2
! ~ ++ -- - + (cast) *(pointer) &(addr) sizeof
3
* / %
4
+ -
5
<< >>
6
< <= > >=
7
== !=
8
&
9
^
10
|
11
&&
12
||
13
?:
14
= += -= *= /= %= ^= |= <<= >>=
15
,

연산자 우선 순위와 결합 방향을 고려하여 프로그래밍하는 것은 프로그래머의 몫이며 프로그래밍은 가독성(간결성)과 효율(길이) 측면에서 고민하게 되는 경우가 자주 발생한다. 한 수식에 부득이하게 연산자를 여러 개를 써야 한다면 괄호 등을 적극 활용하여 우선 순위를 명확히 하는 것이 좋다.

연산자 결합 방향

 한 수식에서 동일한 우선순위를 가진 연산자들이 연속적으로 나타나 있으면 연산자의 결합 방향을 고려하여야 한다. 대부분의 연산자들은 왼쪽에서 오른쪽으로 결합을 한다. 하지만 반대로 오른쪽에서 왼쪽으로 결합하는 연산자가 있다.
  1. 단항연산자, 형변환연산자, sizeof등은 오른쪽에서 왼쪽으로 결합한다.
  2. 조건 연산자 (?) 는 오른쪽에서 왼쪽으로 결합한다.
  3. 대입 연산자는 오른쪽에서 왼쪽으로 결합한다.

[표 2] 연산자 결합 방향 예시
수식
결합 결과
a = x +y - z
a = (x + y) - z
a = x * y / z
a = (x * y) / z
a = x && y || z
a = (x && y) || z
a = y+= z
a = (y+= z)
a = *x++
a = *(x++)

예를 들어서 sA=sY+=sZ 와 같은 표현식은 내부적으로 정해진 결합 순서에 의해서 오른쪽에서 왼쪽으로 결합하겠지만 프로그래머가 아예

sA = (sY += sZ);

와 같이 괄호를 명시하든가 더 가독성을 높이려면

sY += sZ;
sA = sY;

와 같이 두 줄로 나누어 쓰는 것이 더 나아보일 수도 있다. 이는 전적으로 작성자의 성향에 달려있다고 할 수 있다.