홈강좌Rust 입문·중급 47편 중 6편째
Rust 실수와 as — 정수와 실수는 섞어 계산하지 않는다
Rust 실수는 소수점이 있는 숫자이고, 타입을 적지 않으면 f64 가 된다. 정수와 실수를 섞어 계산하면 E0277 로 컴파일이 멈춘다. 9 대신 9.0 처럼 실수로 쓰거나, as 로 타입을 바꿔 맞춘다.
01 실수는 f64 가 기본이다
36.5 처럼 소수점이 있으면 실수다. 실수 타입은 f32 와 f64 둘인데, 타입을 적지 않으면 더 정밀한 f64 가 된다. 요즘 컴퓨터에서는 f64 도 f32 만큼 빠르니 특별한 이유가 없으면 f64 를 쓴다.
02 정수와 섞으면 E0277
섭씨 체온을 화씨로 바꿔 보자. 화씨는 섭씨 × 9 ÷ 5 + 32 다. 공식을 그대로 옮기면 이렇게 된다.
fn main() {
let celsius = 36.5;
let fahrenheit = celsius * 9 / 5 + 32;
println!("{fahrenheit}");
}error[E0277]: cannot multiply `{float}` by `{integer}`
--> src/main.rs:3:30
|
3 | let fahrenheit = celsius * 9 / 5 + 32;
| ^ no implementation for `{float} * {integer}`이 오류는 뒤로 15줄 넘게 이어지지만, 앞의 다섯 줄만 읽으면 된다.
- 무엇 — 실수(
{float})에 정수({integer})를 곱할 수 없다(cannot multiply). - 어디 — 3번째 줄
celsius * 9의*. - 고치는 법 —
help:가 길게 늘어놓는 목록은 지금은 몰라도 된다. 뜻은 "실수끼리는 곱할 수 있다" 는 것이다.
{float} 처럼 중괄호로 감싼 이름은 "실수인 것은 확실한데 f32 인지 f64 인지는 아직 안 정했다" 는 뜻이다. 다른 언어는 정수를 알아서 실수로 바꿔 계산해 주지만, Rust 는 바꿔 주지 않는다. 몰래 바뀌다 정밀도를 잃는 일을 막으려는 것이다.
03 숫자를 실수로 쓰면 된다
9 를 9.0 으로, 나머지도 소수점을 붙여 실수로 쓴다.
fn main() {
let celsius = 36.5;
let fahrenheit = celsius * 9.0 / 5.0 + 32.0;
println!("{celsius} C = {fahrenheit} F");
} Compiling convert v0.1.0 (~/projects/convert)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `target/debug/convert`
36.5 C = 97.7 F04 변수끼리 섞일 때는 as
숫자를 직접 쓸 때는 .0 을 붙이면 되지만, 이미 정수인 변수는 그럴 수 없다. 이때 값 as 타입 으로 타입을 바꾼다. 점수 합계 7 을 2 명으로 나눈 평균을 구해 보자.
fn main() {
let total = 7;
let count = 2;
let average = total as f64 / count as f64;
println!("{average}");
let rounded_down = 3.9_f64 as i32;
println!("{rounded_down}");
} Compiling average v0.1.0 (~/projects/average)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
Running `target/debug/average`
3.5
3total as f64는 정수 7 을 실수 7.0 으로 바꾼다. 둘 다 실수로 바꿨으니 나눗셈 결과가 3.5 다. 5편처럼 정수끼리 나눴다면 3 이었다.3.9_f64는 "f64 타입의 3.9" 라는 뜻이다. 숫자 뒤에_타입을 붙여 타입을 정할 수 있다.- 실수를
as i32로 바꾸면 소수점 아래를 버린다. 반올림이 아니라서 3.9 가 3 이 된다.
05 실습 — 공식이 맞는지 검산하기
공식이 맞는지 두 온도로 확인해 보자. 섭씨 -40 은 화씨로도 -40 이고(두 눈금이 만나는 온도), 물이 끓는 섭씨 100 은 화씨 212 다. 32 는 3편의 const 로 뺐다.
const FREEZING: f64 = 32.0;
fn main() {
let cold = -40.0;
let boiling = 100.0;
println!("{cold} C = {} F", cold * 9.0 / 5.0 + FREEZING);
println!("{boiling} C = {} F", boiling * 9.0 / 5.0 + FREEZING);
} Compiling convert v0.1.0 (~/projects/convert)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `target/debug/convert`
-40 C = -40 F
100 C = 212 F두 값이 다 맞았다. 실수를 찍을 때 소수점 아래가 0 이면 -40.0 이 아니라 -40 으로 줄여 찍는다. 타입은 그대로 f64 다. 정수 하나를 섞어 E0277 을 다시 내 보고, as f64 로 고쳐 보는 것도 좋은 연습이다. 다음 편은 남은 기본 타입 둘, 참·거짓을 담는 bool 과 글자 하나를 담는 char 다.