hyunsu blog

홈강좌Rust 입문·중급 47편 중 6편째

Rust 실수와 as — 정수와 실수는 섞어 계산하지 않는다

목차 · 5
  1. 01실수는 f64 가 기본이다
  2. 02정수와 섞으면 E0277
  3. 03숫자를 실수로 쓰면 된다
  4. 04변수끼리 섞일 때는 as
  5. 05실습 — 공식이 맞는지 검산하기

Rust 실수는 소수점이 있는 숫자이고, 타입을 적지 않으면 f64 가 된다. 정수와 실수를 섞어 계산하면 E0277 로 컴파일이 멈춘다. 9 대신 9.0 처럼 실수로 쓰거나, as 로 타입을 바꿔 맞춘다.

01 실수는 f64 가 기본이다

36.5 처럼 소수점이 있으면 실수다. 실수 타입은 f32 와 f64 둘인데, 타입을 적지 않으면 더 정밀한 f64 가 된다. 요즘 컴퓨터에서는 f64 도 f32 만큼 빠르니 특별한 이유가 없으면 f64 를 쓴다.

02 정수와 섞으면 E0277

섭씨 체온을 화씨로 바꿔 보자. 화씨는 섭씨 × 9 ÷ 5 + 32 다. 공식을 그대로 옮기면 이렇게 된다.

rust
fn main() {
    let celsius = 36.5;
    let fahrenheit = celsius * 9 / 5 + 32;
    println!("{fahrenheit}");
}
text
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줄 넘게 이어지지만, 앞의 다섯 줄만 읽으면 된다.

  1. 무엇 — 실수({float})에 정수({integer})를 곱할 수 없다(cannot multiply).
  2. 어디 — 3번째 줄 celsius * 9 의 *.
  3. 고치는 법 — help: 가 길게 늘어놓는 목록은 지금은 몰라도 된다. 뜻은 "실수끼리는 곱할 수 있다" 는 것이다.

{float} 처럼 중괄호로 감싼 이름은 "실수인 것은 확실한데 f32 인지 f64 인지는 아직 안 정했다" 는 뜻이다. 다른 언어는 정수를 알아서 실수로 바꿔 계산해 주지만, Rust 는 바꿔 주지 않는다. 몰래 바뀌다 정밀도를 잃는 일을 막으려는 것이다.

03 숫자를 실수로 쓰면 된다

9 를 9.0 으로, 나머지도 소수점을 붙여 실수로 쓴다.

rust
fn main() {
    let celsius = 36.5;
    let fahrenheit = celsius * 9.0 / 5.0 + 32.0;
    println!("{celsius} C = {fahrenheit} F");
}
text
   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 F

04 변수끼리 섞일 때는 as

숫자를 직접 쓸 때는 .0 을 붙이면 되지만, 이미 정수인 변수는 그럴 수 없다. 이때 값 as 타입 으로 타입을 바꾼다. 점수 합계 7 을 2 명으로 나눈 평균을 구해 보자.

rust
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}");
}
text
   Compiling average v0.1.0 (~/projects/average)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/average`
3.5
3
  • total 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 로 뺐다.

rust
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);
}
text
   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 다.