{"id":24775115,"url":"https://github.com/vsirotin/si-units","last_synced_at":"2025-08-25T19:14:52.985Z","repository":{"id":62694955,"uuid":"542600036","full_name":"vsirotin/si-units","owner":"vsirotin","description":"Kotlin function and objects for working with SI units like meter, second, as well as currencies and general units like percent. ","archived":false,"fork":false,"pushed_at":"2025-01-21T12:41:07.000Z","size":4421,"stargazers_count":121,"open_issues_count":12,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T15:11:21.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://vsirotin.github.io/si-units/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vsirotin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-28T13:18:39.000Z","updated_at":"2025-03-13T14:52:26.000Z","dependencies_parsed_at":"2023-02-19T00:45:46.788Z","dependency_job_id":"662574c9-6c89-4bdf-9ddf-c11dce884576","html_url":"https://github.com/vsirotin/si-units","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsirotin%2Fsi-units","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsirotin%2Fsi-units/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsirotin%2Fsi-units/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsirotin%2Fsi-units/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vsirotin","download_url":"https://codeload.github.com/vsirotin/si-units/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247361617,"owners_count":20926642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-29T06:37:49.595Z","updated_at":"2025-04-05T16:05:13.429Z","avatar_url":"https://github.com/vsirotin.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Maven Central](https://img.shields.io/maven-central/v/eu.sirotin.kotunil/kotunil-jvm)](https://mvnrepository.com/artifact/eu.sirotin.kotunil/kotunil-jvm)\n[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)\n[![GitHub contributors](https://img.shields.io/github/contributors/vsirotin/si-units)](https://github.com/vsirotin/si-units/graphs/contributors)\n\n[![npm](https://img.shields.io/npm/v/kotunil-js-lib?sort=semver\u0026logo=npm)](https://www.npmjs.com/package/kotunil-js-lib)\n[![npm type definitions](https://img.shields.io/npm/types/v-github-icon?logo=typescript)](https://github.com/vinayakkulkarni/v-github-icon/blob/main/package.json)\n[![npm](https://img.shields.io/npm/dt/kotunil-js-lib?logo=npm)](http://npm-stat.com/charts.html?package=kotunil-js-lib)\n[![npm](https://img.shields.io/npm/dw/kotunil-js-lib?logo=npm)](http://npm-stat.com/charts.html?package=kotunil-js-lib)\n\n![badge-jvm](http://img.shields.io/badge/platform-jvm-DB413D.svg?style=flat)\n![badge-android](http://img.shields.io/badge/platform-android-6EDB8D.svg?style=flat)\n![badge-ios](http://img.shields.io/badge/platform-ios-CDCDCD.svg?style=flat)\n![badge-mac](http://img.shields.io/badge/platform-macos-111111.svg?style=flat)\n![badge-linux](http://img.shields.io/badge/platform-linux-2D3F6C.svg?style=flat)\n![badge-nodejs](https://img.shields.io/badge/platform-jsNode-F8DB5D.svg?style=flat)\n![badge-browser](https://img.shields.io/badge/platform-jsBrowser-F8DB5D.svg?style=flat)\n \n# KotUniL\n\n![alt Genesis rules of International System of Units_(Source: Wikipedia) ](https://github.com/vsirotin/si-units/blob/main/docs/images/si-genesis.png)\n\n**KotUniL** covers all units of **International System of Units** (SI)  \nlike meter, second etc. [(see Wikipedia)](https://en.wikipedia.org/wiki/International_System_of_Units)\nas well as SI- Prefixes (micro, nano etc.) and some other common units like currencies, percentages etc.\n\n**KotUniL (Kotlin Units Library)** a library of functions and objects of Kotlin that meet the following \nrequirements in total:\n1. It allows various formulas to be written in Kotlin in a way maximally similar to the way formulas are written in physics and economics.\n2. It allows analyzing dimensions of results of applications of complicated formulas.\n3. It allows to detect most of the typical errors when working with SI units already at the compilation stage. Errors in incorrect use of physical units in complex formulas are detected in runtime.\n4. It is pure library (no plug-in, no parser etc.), it has no dependencies\n\n\n### Project structure\n\nThe goal of the project is not only to provide a unified set of objects and \nfunctions that allows to use the SI in programs in different programming languages. \nThe project also contains simple applications in all of the target languages that show how to do this. In addition, these applications test the availability of all necessary functions on that target platform.\n\n(So far, applications for only two target platforms have been implemented.)\n\nTherefore, all subprojects of this project are divided into three groups:\n1. [kotunil](https://github.com/vsirotin/si-units/blob/c3f1b87c2fa4b35adc64b676318e27eae3e246e5/kotunil) - implementation of library functionality in Kotlin.\n2. [js-lib](https://github.com/vsirotin/si-units/blob/27117b3ea841f18366fff69c955d25d2f07525b9/js-lib) - JavaScript variant of KotUniL, available as NPM package [kotunil-js-lib](https://www.npmjs.com/package/kotunil-js-lib). \n3. [apps](https://github.com/vsirotin/si-units/blob/c3f1b87c2fa4b35adc64b676318e27eae3e246e5/apps) \napplications that test the functionality of the library on a specific platform.\nIn the moment are test applications as console-application for [Kotlin](https://github.com/sheepdreamofandroids/si-units/blob/39a0afe4d47f78a1a79f6696c242055d0484fcef/apps/jvm/java-console)\nand [Java](\n   https://github.com/vsirotin/si-units/blob/39a0afe4d47f78a1a79f6696c242055d0484fcef/apps/jvm/java-console) platfforms impemented ans web page \nfor [Browser/JavaScript](https://github.com/sheepdreamofandroids/si-units/blob/39a0afe4d47f78a1a79f6696c242055d0484fcef/apps/web_app_js) and [Node/TypeScript](https://github.com/sheepdreamofandroids/si-units/blob/39a0afe4d47f78a1a79f6696c242055d0484fcef/apps/node_ts_app)\n    variants of library. \n4. [kotunil-generators](https://github.com/vsirotin/si-units/blob/c3f1b87c2fa4b35adc64b676318e27eae3e246e5/kotunil-generators) - generators used to accelerate the implementation and testing of the library.\n\nIf you are a developer and you are interested in the source code of the library, \nyou only need part [kotunil](https://github.com/vsirotin/si-units/blob/c3f1b87c2fa4b35adc64b676318e27eae3e246e5/kotunil).\n\n## 1. Getting started\n\n### 1.1 Simple physical formulas\n\nLet's consider some simple examples.\n\n*In Eva's case, a glass broke in her aquarium and water flowed on floor. \nIn aquarium before breakage was 32 liters of water.\nEva's room is 4 m. wide and 4.3 long. \nHow high in mm. is water now in Eva's room with assumption that it stayed there \nand did not flow away?*\n\nThe solution in Kotlin can be written in one line. For didactic reasons like introduce two auxiliary variables s and h.\n\n```kotlin\nval s = 4.m * 4.3.m\nval h = 32.l/s   \nprint(\"Water height is ${h.mm} mm.\")\n```\n\n### 1.2 How to properly write KotUniL's formulas\nKotUniL is a multiplatform library.\nYou can read about how to properly write physics and other formulas\nusing the objects and functions of the KotUniL library in document\n[\"Rules for writing KotUniL formulas in different programming languages\"](https://github.com/vsirotin/si-units/blob/c3f1b87c2fa4b35adc64b676318e27eae3e246e5/RulesWritingFormulas.md).\n\n### 1.3 Dimension analysis\nPlease note that the variable **s** is physical dimension **m2** (square meter) and **h** - **m** (simple meter).\nFurthermore, in this example we also used liters (**l**), which have dimension **m3** (cubic meters). \n\nUsing the built-in function **unitSymbols()** you can determine the dimension of any object in terms of SI standard.\n\n```kotlin\nval s = 4.m * 5.m\nassertEquals(\"m2\", s.unitSymbols())\n\nval x = 20.l\nassertEquals(\"m3\", x.unitSymbols())\n\nval h = x/s\nassertEquals(\"m\", h.unitSymbols())\n\nval y = 1.2.s\nassertEquals(\"s\", y.unitSymbols())\n\nval z = x/y\nassertEquals(\"m3/s\", z.unitSymbols())\n```\n\nUsing the built-in function **categorySymbols()** \nyou can analyze dimensions of physical units in \"academic\" manner.\n\n```kotlin\nval s = 4.m * 5.m\nassertEquals(\"L2\", s.categorySymbols())\n\nval x = 20.l\nassertEquals(\"L3\", x.categorySymbols())\n\nval h = x/s\nassertEquals(\"L\", h.categorySymbols())\n\nval y = 1.2.s\nassertEquals(\"T\", y.categorySymbols())\n\nval z = x/y\nassertEquals(\"L3T-1\", z.categorySymbols())\n```\n\n### 1.4 Type safety\n\nPhysical units of the same dimension can be added, subtracted and compared.\nIf you try to do this with units of different types, \nyou will get either compilation errors (for simple units) \nor run-time errors for complicated units. \n\n```kotlin\n//val x = 1.m + 2 compilation error\n//val y = 20.l/(4.m * 5.m) + 14 compilation error\n\n//Complex errors will be found in runtime:\nval exception = assertFailsWith\u003cIllegalArgumentException\u003e(\n    block = { 1.m + 2.s }\n)\nassertTrue(exception.message!!.startsWith(COMPATIBILITY_ERR_PREFIX))\n```\n\nOf course, a safety with an exception is not a classic type safety, that shows up during compilation time. \nHowever, it is better than letting the metre and the second add up. \n\nWhen using SI such error is found during the first unit test.  \n(Reminder: just such errors led in the past to terrible technical catastrophes, \nsee e.g. https://en.wikipedia.org/wiki/Mars_Climate_Orbiter).\n### 1.4 Comparison of objects\n\nPhysical objects can be compared only if they have the same dimensions. \n\n```kotlin\nassertTrue(5.m \u003e 4.1.m)\n\nassertTrue(20.2*m3 \u003e 4.2*m3)\n\nassertTrue(2.2*kg*m/s \u003c 4.2*kg*m/s)\n```\n\nOtherwise, you will get a run-time error.\n\n```kotlin\nval v1 = 2.4.m\nval v2 = 2.4.s\n\nval exception = assertFailsWith\u003cIllegalArgumentException\u003e(\n    block = { v1 \u003e= v2 }\n)\nassertTrue(exception.message!!.startsWith(COMPATIBILITY_ERR_PREFIX))\n```\n\nor:\n\n```kotlin\nval v1 = 2.4.m*kg/s\nval v2 = 2.4.s*m3/ μV\n\nval exception = assertFailsWith\u003cIllegalArgumentException\u003e(\n    block = { v1 \u003e= v2 }\n)\nassertTrue(exception.message!!.startsWith(COMPATIBILITY_ERR_PREFIX))\n```\n\nWith KotUniL you can also compare, add and divide the objects that are defined differently, but have the same physical dimension.  \nIn the example below the objects with the dimension \"hertz\" (1/second) are used.\n```kotlin\nassertEquals(0.9.Hz, 0.9/s)\nassertEquals(0.9.Hz, 5/s - 4.1.Hz)\n```\n\n## 2. How to use\n\n### 2.1 Production mode\nKotUniL distributed as Kotlin-library via MavenCentral.\nDependency for **build.gradle.kts**:\n\n```kotlin\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(\"eu.sirotin.kotunil:kotunil-jvm:X.Y.Z\")\n}\n```\nwhere X.Y.Z ist last published version of KotUniL in MavenCentral.\nYou can see the number of this version at the head of this file after icon with \nthe text \"maven-central\". \n\nDependency for Maven/pom:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eeu.sirotin.kotunil\u003c/groupId\u003e\n    \u003cartifactId\u003ekotunil-jvm\u003c/artifactId\u003e\n    \u003cversion\u003eX.Y.Z\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### 2.2 Development mode\n\nAt the moment KotUniL is developing rapidly. \nTo enable you to try the latest features of KotUniL use the following configuration at KTS:\n\n```kotlin\nimplementation(\"eu.sirotin.kotunil:kotunil-jvm:+\")\n```\n\nand by Maven:\n\n```xml\n\u003cversion\u003eLATEST\u003c/version\u003e\n```\n\n### 2.3 Using only source code\nIf you want to use it as source code, \ncopy into your project all production files from \n**src/commonMain/kotlin/eu/sirotin/kotunil**.\n\n\n## 3. Deeper into details\n\n### 3.1 Base Units\n\nSI standard defines 7 base units, as well as some derived units \nand accepts historically established non-SI units.\n\nThe table below listed Base SI units.\n\nYou can define a physical unit by multiplying \na value at unit variable or from a number (Double, Int etc.) \nif you write SI symbol after a dot after a number.\n\n```kotlin\n1*s == 1.0.s\ns == 1.s\ns = 1.0.s\n```\n\nIn special cases you can also create unit using a class constructor.\n\n```kotlin\nSecond(1.0) == 1.s\n```\n\n| SI Base Unit | Unit symbol |\n|--------------|-------------|\n| second       | s           |\n| metre        | m           | \n| kilogram     | kg          |\n| ampere       | A           | \n| kelvin       | K           | \n| mole         | mol         | \n| candela      | cd          | \n\nThe name of the class differs from the name \nof the unit by first capital letter. \n\n### 3.2 Derived Units\n\nSI standard defines beside base unit also 22 derived units. \nThey are listed in the table below.\nDo not be surprised if you encounter in this table \nand in KotUniL library unusual for identifiers symbols like Ω. \nIt is possible because according to Kotlin's specification most common unicode symbols can be used in Kotlin identifiers (see paragraph \"1.2.4 Identifiers\" in Kotlin Specification https://kotlinlang.org/spec/pdf/kotlin-spec.pdf).\nDerived units can be used just like base units.\nBoth types can be used in a formula by multiplication or division.\n\n| SI Derived Unit | Unit symbol | Formula                                            | \n|-----------------|-------------|----------------------------------------------------|\n| radian          | rad         | m/m                                                |  \n| steradian       | sr          | m2/m2                                              |  \n| hertz           | Hz          | 1/s                                                |  \n| newton          | N           | kg*m/(s `^` 2)                                     |  \n| pascal          | Pa          | kg/(m * (s `^` 2))                                 |  \n| joule           | J           | kg*(m2)/(s `^` 2)                                  |  \n| watt            | W           | kg*(m2)/(s `^` 3)                                  |  \n| coulomb         | C           | s*A                                                |  \n| volt            | V           | kg\\*m2*(s `^` -3) * (A `^` -1)                     |  \n| farad           | F           | (kg  `^` -1) * (m  `^` -2) * (s `^` 4) * (A `^` 2) |  \n| ohm             | Ω           | kg*m2 * (s `^` -3) * (A `^` -2)                    |  \n| siemens         | S           | (kg `^` -1) * (m `^` -2) \\*(s `^` 3)* (A `^` 2)    |  \n| weber           | Wb          | kg*(m2) * (s `^` -2) * (A `^` -1)                  |  \n| tesla           | T           | kg* (s `^` -2) * (A `^` -1)                        |  \n| henry           | H           | kg* (m2)\\*(s `^` -2)*(A `^` -2)                    |  \n| degreeCelsius   | Celsius     | (K `^` 1)                                          |  \n| lumen           | lm          | ((cd `^` 1)*sr)                                    |  \n| lux             | lx          | cd\\*sr*(m `^` -2)                                  |  \n| becquerel       | Bq          | (s `^` -1)                                         |  \n| gray            | Gy          | (m2)*(s `^` -2)                                    |  \n| sievert         | Sv          | (m2)*(s `^` -2)                                    |  \n| katal           | kat         | (mol * (s `^` -1))                                 | \n\nAlso, do not wound yourself when you see the **^** symbol. \nKotlin has no operator for power, but a function. \nKotUniL was extended with this infix function. \nUnfortunately, with it can not set proper priority for this function. \nAlthough this looks like a \"real\" operator, \nfor keeping proper operation prioritization, \nyou have to put it in parentheses.\n\n\n#### Real-life example:\n\nMiller family makes a trip to the nature. \nThey brought a solar panel and immediately turned on at the \nexcursion site. Solar produced 12 volts and 7 amps 2 hours. \nProduced electricity was stored in a storage tank. \nStorage efficiency is 85%.\nAfter that, Mrs. Miller decided to prepare the tea in boiler. \nTo prepare hot water for tea with boilers with 500 watt strength, \nthe water should be boiled for 8 min.\nThe question, is stored in memory electricity enough for that?\n\n```kotlin\n        val producedElectricity = 12.V * 7.A * 2.h\n        val savedElectricity = producedElectricity * 85.`%`\n        val neededElectricity = 0.5.kW * 8.min\n        val dif = savedElectricity - neededElectricity\n        assertTrue(dif \u003c 0.W*h) //Comparison in KotUniL\n        assertTrue(dif.value \u003c 0) //Comparison dimensionless\n```\n\nNote that for convenience we use here the symbol `%`. \nThis is also extension of Kotlin in our library.\n\nRegarding this and similar extensions, see the statement:\n\"Kotlin supports escaping identifiers by enclosing\nany sequence of characters into backtick (\\`) characters,\nallowing to use any name as an identifier.\"\n(See paragraph 1.2.4 \"Identifiers\" in Kotlin specification\nhttps://kotlinlang.org/spec/syntax-and-grammar.html#grammar-rule-Identifier).\nThe character backtick (`) (UTF-8 code U+0060) is not equal\nto the apostrophe characters on the keyboard (UTF-8 code U+0027).\nTo use it, you better copy it directly from this example.\n\n**Please note: such identifiers currently work only on Jvm platform.**\n\nMost derived units can be derived from Based Units \nor from other Derived Units in different ways.  \nLook at the example of Tesla:\n\n```kotlin\nassertEquals(T,\tkg * (s `^` -2) * (A `^` -1))\nassertEquals(T,\tWb/ m2)\n```\n\n### 3.3 Own Derive Units\n\nYou can also define your own Derived Units.\nConsider a not properly scientifically proven example.\nLet's imagine that the melting speed of snow in mountains \nis proportional to the duration and temperature above 0 °C. \nThis will be our new Derived Unit.\nIf current snow thickness is 10 cm, \nwhat proportion will be melted in 5 hours at 20 °C?  \nThe code below also shows the nice side of Kotlin - \na possibility to use Unicode symbols, e.g. Greek letters.\n\n```kotlin\n        val ζ = 10.μm/(h*K) //melting speed\n        val τ = 10.cm\n        val t = 20.`°C`\n        val ξ = 5.h*(t - 0.`°C`)\n        val σ = ζ*ξ //melting height\n        val α = σ/τ //melting ration\n        assertEquals(1.0, α.`as %`, ε) //α.`as %` - Ratio presented in percents\n```\n\nPlease note, how you can present calculation result in percents: \n**α.`as %`** - ratio presented in percents.\n\nε is some small value for tolerance by comparison of double numbers. \nThis is also one of the variables defined in KotUniL\n\n### 3.4 SI-Prefixes \n\nSI standard also defines SI prefixes \nand rules for their use with units ( Base and Derived). \nSI Units library implements this mechanism. \nThe table of prefixes and their values can be seen \nin the table below. \n\n| Prefix | Symbol | Degree |\n|--------|--------|--------|\n| quetta | Q      | 30     | \n| ronna  | R      | 27     | \n| yotta  | Y      | 24     | \n| zetta  | Z      | 21     | \n| exa    | E      | 18     | \n| peta   | P      | 15     | \n| tera   | T      | 12     | \n| giga   | G      | 9      | \n| mega   | M      | 6      | \n| kilo   | k      | 3      | \n| hecto  | h      | 2      | \n| deca   | da     | 1      | \n| deci   | d      | -1     | \n| centi  | c      | -2     | \n| milli  | m      | -3     | \n| micro  | μ      | -6     | \n| nano   | n      | -9     | \n| pico   | p      | -12    | \n| femto  | f      | -15    | \n| atto   | a      | -18    | \n| zepto  | z      | -21    | \n| yocto  | y      | -24    |\n| ronto  | r      | -27    |\n| quecto | q      | -30    |\n\nIn example below we check that one kilometer is equal \nto milliard of micrometer.  \n\n```kotlin\nval d = km - (10 `^` 9) * μm\nassertTrue(abs(d.value) \u003c ε)\n```\n\n### 3.5 Non-SI units accepted for use with SI\n\nMany non-SI units continue to be used in the scientific, \ntechnical, and commercial literature.\nKotUniL Library implements these units.\nThey are listed in the table below.\n\n\n| Quantity               | \tName                                  | \tSymbol | \tValue in SI units                      |\n|------------------------|----------------------------------------|---------|-----------------------------------------|\n| time\t                  | minute\t                                | min\t    | 1 min = 60 s                            |\n| time                   | hour                                   | \th\t     | 1 h = 60 min = 3600 s                   |\n| time                   | day                                    | \td      | \t1 d = 24 h = 86400 s                   |\n| length\t                | astronomical unit                      | \tau\t    | 1 au = 149597870700 m                   |\n| plane and phase angle\t | degree\t                                | °       | \t1° = π*rad/180                         |\n| plane and phase angle\t | arcminute                              | \t′      | \t1′ = 1°/60 = π*rad/10800               |\n| plane and phase angle\t | arcsecond\t″\t1″ = 1′ /60 = π*rad/648000 |\n| area                   | \thectare\t                              | ha\t     | 1 ha = 1 hm2 = 10^4 m2                  |\n| volume                 | \tlitre                                 | \tl, L\t  | 1 l = 1 L = 1 dm3 = 10^3 cm3 = 10^−3 m3 |\n| mass\t                  | tonne (metric ton)\t                    | t\t      | 1 t = 1 Mg = 10^3 kg                    |\n| mass\t                  | dalton\t                                | Da\t     | 1 Da = 1.660539040(20)×10^−27 kg        |\n| energy\t                | electronvolt                           | \teV     | \t1 eV = 1.602176634×10^−19 J            |\n\n\n**Example:**\n\nA city park has area 2.3 hectares. \nDuring a rain 1 mm of water had fallen from the sky.  \nIf there was no rain, the park should be watered \nwith water from car cisterns. A car cistern can carry 4 tons of water.\nHow many cisterns are needed to achieve \nthe same effect as in case of rain?\nReminder: density of watter is 1 kg/l\n\n```kotlin\nval s = 1.ha\nval ω = s*100.mm //water volume\nval ρ = kg/l //density of watter is 1 kg/l\nval τ = ω * ρ //common water weight of rain\nval n = τ/4.t\nassertEquals(250.0, n.value, ε)\n```\n\n### 3.6 Currencies\nKotUniL library lets you use currencies in your calculations.\n\nSome example:\n\nA householder has decided to cover the floor with tiles in one of his rooms.\n\nHe has bought 16,5 sqm of tiles for 52 €/sqm.\nHow much does he pay for his tiles?\n\n```kotlin\nval prise = 52.`€`/m2\nval s = 16.5*m2\nval cost = s*prise\nassertEquals(\"858,00 EUR\", cost.show(\"%.2f\"))\nassertEquals(\"EUR\", cost.unitSymbols())\n```\n\n### 3.7 Things\nSometimes you need an abstract unit like \"thing\". For example:\n\nEvery good guy has 30 different things per liter in his pocket.\nJan is a good guy and his pocket is 0.3 liters big.\nHow many things can his mom find in Jan's pocket? \n\n```kotlin\nval p = 30.`#`/l\nval n = 0.3.l * p\n\nassertEquals(\"9 #\", n.show(\"%.0f\"))\nassertEquals(\"#\", n.unitSymbols())    \n```\n\n### 3.8 Full implementation of Kotlin's operators for units\nLibrary completely implements Kotlin's operators like:\nUnare operators:\n\n```kotlin\na = +b\na = -b\n```\n\nAugment assignments:\n\n```kotlin\na +=b\na -=b\na *=b\na /=b\na %=b\n```\n\n**Attention**: Operators\n\n```kotlin\na++ \n```\n\nand\n\n```kotlin\na-- \n```\n**are not implemented** due to known bugs Kotlin compiler\n(See https://youtrack.jetbrains.com/issue/KT-24800)\n\nHead image: Genesis rules of International System of Units (Source: [Wikipedia](https://en.wikipedia.org/wiki/International_System_of_Units))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsirotin%2Fsi-units","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvsirotin%2Fsi-units","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsirotin%2Fsi-units/lists"}