Kasalahan pembulatan sajrone transisi

Ing Bavaria, nilai rata-rata sakabèhé \(2{,}33\) nuduhaké kesesuaian kanggo Gymnasium \(2{,}34\) ora. Ing cutoff sing cetha iki, urutan rong operasi pembulatan bisa nemtokaké sisih endi bocah tiba. Günther Felbinger ngrembug babagan potensial akibat saka efek pembulatan iki ing postingan blog . Amarga minat murni, aku ngetung efek kasebut dhéwé ing kabeh kombinasi nilai sing diidinake ing model kasebut.


Pitakonan utamaku yaiku: Sepira kerepe pembulatan awal menyang nilai kabeh subjek ndadékaké jinis itungan sekolah sing béda tinimbang itungan sing nggunakaké rata-rata subjek sing ora dibunderaké? Salajengipun, bakal menarik kanggo ndeleng apa sing owah yen rata-rata saben subjek (kaya sing disaranake ing kana) wiwitane dibunderaké mung dadi siji desimal.

Miturut Bagean 6 saka Peraturan Sekolah Dasar Bavaria, nilai rata-rata diitung saka nilai ing basa Jerman, Matematika, lan Studi Lokal lan Umum. Peraturan implementasine nemtokake watesan nganti lan kalebu \(2{,}33\) lan nganti lan kalebu \(2{,}66\) . Ing model pitungan ing ngisor iki, saben rata-rata sakabèhé dipotong dadi rong angka desimal lan ora dibulatké manèh. Dadi, contoné...

\[
\frac{2{,}33+2{,}34+2{,}34}{3}=2{,}3366\ldots \longrightarrow 2{,}33.
\]

Iki penting banget kanggo klasifikasi: \(2{,}3366\ldots\) ora dadi \(2{,}34\) , nanging \(2{,}33\) lan mulane isih cukup kanggo sekolah dasar.

Entri awal nggambarake pembulatan awal kanthi nilai rata-rata spesifik subjek sing diasumsikake \(1{,}6\) , \(2{,}6\) , lan \(2{,}6\) . Saka iki, kabeh nilai \(2\) , \(3\) , lan \(3\) diturunake dhisik. Rata-rata yaiku

\[
\frac{2+3+3}{3}=2{,}6666\ldots \longrightarrow 2{,}66,
\]

sing tegese siswa kasebut ora nduweni kualifikasi kanggo mlebu sekolah dasar langsung. Nanging, tanpa pembulatan menyang nilai sakabèhé, asil ing conto hipotetis bakal dadi...

\[
\frac{1{,}6+2{,}6+2{,}6}{3}=2{,}2666\ldots \longrightarrow 2{,}26.
\]

Ing conto kapindho, pembulatan kerjane ing arah sing ngelawan: \(2{,}4\) , \(3{,}4\) lan \(2{,}4\) dadi nilai cathetan sakabèhé \(2\) , \(3\) lan \(2\) , kanthi resmi \(2{,}33\) . Nanging, nilai sing ora dibunderake ngasilake \(2{,}73\) . Conto-conto kasebut kanthi jelas nduduhake efek kasebut. Nanging, durung nuduhake sepira kerepe kedadeyan utawa apa akibat saka metode pembulatan sing beda.

Mulane, kanggo itunganku, aku nggunakake ruang asil sing jelas. Saben rata-rata subjek bisa dadi salah siji saka nilai \(501\) ing njero.

\[
1{,}00,\, 1{,}01,\, 1{,}02,\, \ldots, \, 5{,}99, \, 6{,}00
\]

Umpamane. Aku nimbang kabeh kombinasi urutan basa Jerman, matematika, lan studi lokal lan umum kanthi padha. Dadi, ana

\[
501^3=125\,751\,501
\]

Kasus. Mula, model iki ora ambigu, nanging digawe-gawe: Model iki nganggep rata-rata subjek sing disebarake kanthi rata, kamardikan telung subjek, lan langkah-langkah persis sepersatus. Model iki ora nggambarake distribusi nyata bocah-bocah sekolah dasar Bavaria.

Kanggo telung subjek tegese \(d,m,h\) kita nulis

\[
A(d,m,h)=\frac{\left\lfloor 100\cdot\frac{d+m+h}{3}\right\rfloor}{100}
\]

kanggo rata-rata sakabèhé sing dipotong dadi rong panggonan desimal. Saiki kita mbandhingaké telung cara pitungan.:

\[
\begin{aligned}
A_0 &= A(\jeneng operator{bunder}(d),\jeneng operator{bunder}(m),\jeneng operator{bunder}(h)),\\
A_1 &= A(\jeneng operator{bunder}_1(d),\jeneng operator{bunder}_1(m),\jeneng operator{bunder}_1(h)),\\
A_\mathrm{ref} &= A(d,m,h).
\end{aligned}
\]

\(A_0\) cocog karo itungan nggunakake nilai wutuh, \(A_1\) cocog karo proposal kanthi siji desimal, lan \(A_\mathrm{ref}\) cocog karo referensi sing ora dibunderake ing model kasebut. Itungan kasebut bisa dileksanakake langsung ing Rust , contone.:

const SCHOOL_GYMNASIUM: i32 = 0;
const SCHOOL_REALSCHULE: i32 = 1;
const SCHOOL_MITTELSCHULE: i32 = 2;
const FLOAT_TOLERANCE: f64 = 1e-9;

#[derive(Clone, Copy, Default)]
struct Statistic {
    conflict_count: u64,
    total_count: u64,
}

fn determine_school(average: f64) -> i32 {
    if average <= 2.33 {
        return SCHOOL_GYMNASIUM;
    }
    if average <= 2.66 {
        return SCHOOL_REALSCHULE;
    }
    SCHOOL_MITTELSCHULE
}

fn calculate_average(note_deutsch: f64, note_mathe: f64, note_hsu: f64) -> f64 {
    let average = (note_deutsch + note_mathe + note_hsu) / 3.0;
    ((average + FLOAT_TOLERANCE) * 100.0).floor() / 100.0
}

fn round_to_whole_grade(grade: f64) -> f64 {
    grade.round()
}

fn round_to_one_decimal(grade: f64) -> f64 {
    (grade * 10.0).round() / 10.0
}

fn normalize_grade(grade: f64) -> f64 {
    (grade * 100.0).round() / 100.0
}

fn percentage(count: u64, total: u64) -> f64 {
    count as f64 / total as f64 * 100.0
}

fn main() {
    let mut combination_count = 0;
    let mut official_reference_conflicts = 0;
    let mut official_proposal_conflicts = 0;
    let mut proposal_reference_conflicts = 0;
    let mut statistics = [Statistic::default(); 4];

    let mut note_deutsch = 1.0;
    while note_deutsch <= 6.0 {
        let mut note_mathe = 1.0;
        while note_mathe <= 6.0 {
            let mut note_hsu = 1.0;
            while note_hsu <= 6.0 {
                combination_count += 1;

                let official_average = calculate_average(
                    round_to_whole_grade(note_deutsch),
                    round_to_whole_grade(note_mathe),
                    round_to_whole_grade(note_hsu),
                );
                let proposed_average = calculate_average(
                    round_to_one_decimal(note_deutsch),
                    round_to_one_decimal(note_mathe),
                    round_to_one_decimal(note_hsu),
                );
                let reference_average =
                    calculate_average(note_deutsch, note_mathe, note_hsu);
                let official_school = determine_school(official_average);
                let proposed_school = determine_school(proposed_average);
                let reference_school = determine_school(reference_average);

                if official_average == 3.0 {
                    statistics[0].total_count += 1;
                    if reference_school != SCHOOL_MITTELSCHULE {
                        statistics[0].conflict_count += 1;
                    }
                }
                if official_average == 2.66 {
                    statistics[1].total_count += 1;
                    if reference_school == SCHOOL_GYMNASIUM {
                        statistics[1].conflict_count += 1;
                    }
                }
                if official_average == 2.33 {
                    statistics[2].total_count += 1;
                    if reference_school != SCHOOL_GYMNASIUM {
                        statistics[2].conflict_count += 1;
                    }
                }
                if official_average == 2.66 {
                    statistics[3].total_count += 1;
                    if reference_school == SCHOOL_MITTELSCHULE {
                        statistics[3].conflict_count += 1;
                    }
                }

                if official_school != reference_school {
                    official_reference_conflicts += 1;
                }
                if official_school != proposed_school {
                    official_proposal_conflicts += 1;
                }
                if proposed_school != reference_school {
                    proposal_reference_conflicts += 1;
                }

                note_hsu = normalize_grade(note_hsu + 0.01);
            }
            note_mathe = normalize_grade(note_mathe + 0.01);
        }
        note_deutsch = normalize_grade(note_deutsch + 0.01);
    }

    println!(
        "official/reference: {}%",
        percentage(official_reference_conflicts, combination_count)
    );
    println!(
        "official/proposal: {}%",
        percentage(official_proposal_conflicts, combination_count)
    );
    println!(
        "proposal/reference: {}%",
        percentage(proposal_reference_conflicts, combination_count)
    );
    for (index, statistic) in statistics.iter().enumerate() {
        println!(
            "#{}: {}% ({}/{})",
            index + 1,
            percentage(statistic.conflict_count, statistic.total_count),
            statistic.conflict_count,
            statistic.total_count
        );
    }
}

Toleransi cilik ing calculate_average nyegah nilai kaya \(2{,}67\) amarga representasi float binar, iku salah dianggep \(2{,}669999\ldots\) dipotong. normalize_grade Salajengipun, iki nyuda saben nilai loop bali menyang kothak urutan satus. Paling ora ana rong nilai rata-rata sing beda. \(1/300\) kapisah; toleransi saka \(10^{-9}\) mulane cukup cilik kanggo ora ngowahi kasus wates nyata.

Program iki dikompilasi lan diwiwiti karo

rustc -O calc.rs && ./calc

Program iki ngulang kabeh kombinasi \(125\,751\,501\) lan ngasilake:

PerbandinganPorsi
Nilai sakabèhé lawan rata-rata subjek sing ora dibunderaké\(10{,}4411\,\%\)
Nilai sakabèhé dibandhingake karo proposal nganggo siji angka desimal\(10{,}1521\,\%\)
Proposal kanthi siji angka desimal dibandhingake karo rata-rata ahli sing ora dibunderake\(0{,}6615\,\%\)

Nilai utama kanggo aku yaiku \(10{,}4411\,\%\): Ing luwih saka siji saka sepuluh kombinasi, pembulatan awal menyang nilai sakabèhé ndadékaké jinis sekolah sing diitung béda karo referensi sing ora dibunderaké. Proporsi iki mung njlèntrèhaké efek pembulatan ing model sing dipilih.

Ngalih menyang rata-rata ahli kanthi siji panggonan desimal bakal nyebabake klasifikasi sing beda ing \(10{,}1521\,\%\) saka kabeh kasus model dibandhingake karo metode sadurunge. Nanging, perbandingan katelu penting banget: dibandhingake karo referensi sing ora dibunderake, metode kanthi siji panggonan desimal mung nyisakake \(0{,}6615\,\%\) kasus sing nyimpang. Penyimpangan saka referensi kasebut mudhun nganti

\[
1-\frac{0{,}6615}{10{,}4411}\approx 93{,}7\,\%.
\]

Iki, kanggo aku, persis minangka akibat sing kudu dipertanyakan saka metode pitungan saiki: prestasi khusus subjek sing diasumsikake tetep ora owah; mung titik wektu nalika pembulatan kedadeyan sing bisa ngowahi jinis sekolah sing diitung. Sanajan ngetung nganggo siji desimal ora ngilangi efek iki kanthi lengkap, nanging nyuda efek kasebut kanthi signifikan ing model kasebut.

Nanging, angka-angka iki ora ngandhani pira bocah sing sejatine kena pengaruh. Nilai rapor ora mesthi digawe minangka rata-rata sing dibulatke kanthi mekanis, kinerja akademik ora kasebar kanthi seragam utawa independen, lan pilihan jinis sekolah sing nyata ora mung gumantung marang telung angka iki. Pitunganku njawab pitakonan sing luwih spesifik: Sepira kerepe pembulatan ngganti nilai sing diitung nalika kabeh kombinasi nilai satus kemungkinan padha?

Pungkasan, perbandingan karo postingan asli: Tingkat sakabèhé sing kasebut ing kana, kira-kira \(10\,\%\) cedhak karo \(10{,}4411\,\%\) -ku. Nanging, itunganku ora ngonfirmasi papat kasus individu, saben dilapurake minangka \(1/6 \approx 17\,\%\) Kanggo "ora mlebu sekolah menengah kanthi \(3{,}00\) ", "ora mlebu sekolah dasar kanthi \(2{,}33\) ", "wis sekolah dasar kanthi \(2{,}66\) ", lan "wis mlebu sekolah menengah kanthi \(2{,}66\) \(1{,}4615\,\%\) \(59{,}6096\,\%\) \(1{,}2023\,\%\) \(62{,}9395\,\%\) .

Papat nilai kasebut minangka probabilitas kondisional kanthi klompok referensi sing ukurane beda. Tanpa ruang sampel sing ditetepake kanthi beda \(1/6\) ora bisa dijupuk saka nilai kasebut. Pitunganku kanthi mangkono ngonfirmasi efek pembulatan, nanging ora probabilitas individu kasebut. Ing kasus apa wae, pernyataan babagan jumlah nyata bocah sing kena pengaruh mbutuhake distribusi nilai nyata lan katergantungane.

Bali