turns 0.1.2

Fixed-point angles modulo 2π backed by unsigned integers.
Documentation
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

- Build: `cargo build`
- Run all tests: `cargo test`
- Run a single test: `cargo test <name>` (e.g. `cargo test display_three_pi_over_two`)
- Run tests under `no_std`: `cargo test --no-default-features --features libm`
- Lint: `cargo clippy --all-targets`
- Format: `cargo fmt` (check-only: `cargo fmt --check`)

Both feature configurations (default `std` and `--no-default-features --features libm`) must build and pass tests; CI exercises both as well as clippy and fmt checks.

## Architecture

Single-file crate (`src/lib.rs`) exporting `Angle<T>(pub T)`, a fixed-point angle where the full range of an unsigned integer `T` maps to one turn (2π). Integer wraparound _is_ the modular arithmetic — this is the core design idea; prefer wrapping arithmetic over explicit `% TAU`.

Key invariants and conventions:

- **Raw encoding.** The raw value `self.0` encodes angle as `raw / 2^N · 2π`, so `T::max_value() / 2 + 1` equals π. `Angle::<T>::PI`, `FRAC_PI_2`, etc. are defined via the `impl_consts!` macro and derived from this formula.
- **Two layers of impls.** Generic impls (`impl<T: SomeTrait> Angle<T>`) provide the bulk of behavior; the `impl_consts!` macro specializes per-type constants (`ZERO`, `PI`, `FRAC_PI_*`) for `u8`, `u16`, `u32`, `u64`, `u128`, `usize`. `Display` is generic over `T: PrimInt + Display`, not per-type.
- **Operator semantics.** `Add`/`Sub`/`Neg`/`Mul<T>` use _wrapping_ arithmetic (`WrappingAdd`, etc.) so `` wraps to `0`. `Div<T>`/`Rem<T>` are plain integer ops on the raw value. `checked_mul`/`checked_div`/`checked_rem` surface overflow/div-by-zero as `Option`.
- **Fractional representation.** `to_frac()` returns `(num, den)` reduced such that `angle = num·π/den` (den is always a power of two). `from_frac(num, den)` is the inverse and is exact for `den` that divides π's raw value (any power of two ≤ `2^(N-1)`) — which covers every `(num, den)` `to_frac` produces, guaranteeing round-trip. `Display` is implemented on top of `to_frac`.
- **Float conversions.** `from_radians`/`to_radians`/`from_degrees`/`to_degrees`/`from_atan2` are generic over `F: Float + FloatConst + Euclid`. Non-finite inputs coerce to the zero angle (do not panic).
- **Cross-width casts.** `cast::<U>()` widens by shifting into the top bits and narrows by keeping top bits — the angle is preserved up to the target's resolution.

## no_std

`#![cfg_attr(not(feature = "std"), no_std)]`. Transcendentals require either the `std` or `libm` feature (both re-exported through `num-traits`). Tests live inside the lib's no_std scope, so the test module uses `extern crate alloc; use alloc::format;` — any new test that needs `format!` or heap allocation must go through `alloc`.

## Version control

Repo uses `jujutsu` (`jj`). Do not squash, rebase, or push unless explicitly asked.