base-converter/lib/calculations.dart

144 lines
3.8 KiB
Dart

import 'dart:math';
String decimalToBase(int number, toBase) {
//current base as integer
String tmpBase = toBase.toUpperCase();
if (tmpBase == "HEX") tmpBase = "16";
bool negative = number < 0;
if (negative) number *= -1;
String res = "";
switch (tmpBase) {
case "BCD":
String n = number.toString();
for (int i = 0; i < n.length; i++) {
String digit = decimalToBase(int.parse(n[i]), "2");
int missingZeros = 4 - digit.length;
for (int i = 0; i < missingZeros; i++) {
digit = "0" + digit;
}
res += digit;
}
if (negative) res = "-" + res;
break;
case "2CP":
String binary = decimalToBase(number, 2);
bool gotOne = false;
if (negative) {
for (int i = 0; i < binary.length; i++) {
if (gotOne) {
if (binary[i] == "1")
binary[i] == "0";
else
binary[i] == "1";
} else {
if (binary[i] == "1") gotOne = true;
}
}
res = binary;
} else {
res = "0" + binary;
}
break;
default:
int base = int.parse(tmpBase); //current base as integer
List<int> digits = [];
while (number != 0) {
digits.add(number % base);
number = number ~/ base;
}
digits = digits.reversed.toList();
for (int i = 0; i < digits.length; i++) {
if (digits[i] >= 10) {
res += String.fromCharCode(digits[i] + 55);
} else {
res += digits[i].toString();
}
}
if (negative) res = "-" + res;
break;
}
return res;
}
String baseToDecimal(String number, String pBase) {
bool negative = number.startsWith('-');
if (negative) number = number.split('-')[1];
//current base as integer
String tmpBase = pBase.toUpperCase();
if (tmpBase == "HEX") tmpBase = "16";
String cBase = tmpBase;
if (cBase == "BCD" || cBase == "2CP") cBase = "2";
int controlBase = int.parse(cBase);
for (int i = 0; i < number.length; i++) {
if (charToDigit(number, i) >= controlBase) {
return "error-invalid-number-for-base";
}
}
String res = "";
switch (tmpBase) {
case "BCD":
int missingZeros = (4 - number.length % 4) % 4;
for (int i = 0; i < missingZeros; i++) number = "0" + number;
for (int i = 0; i < number.length; i += 4) {
String n = number[i];
n += number[i + 1];
n += number[i + 2];
n += number[i + 3];
String n1 = baseToDecimal(n, "2");
if (int.parse(n1) > 9) return "error-bcd-greater-nine";
res += n1;
}
break;
case "2CP":
if (negative) {
return "error-negative-cp2";
}
int dres = 0;
number = number.split('').reversed.join('').toString();
for (int i = 0; i < number.length; i++) {
int add = int.parse(number[i]) * pow(2, i).toInt();
if (i == number.length - 1) add *= -1;
dres += add;
}
res = dres.toString();
break;
default:
int base = int.parse(tmpBase);
List<int> digits = [];
// Get the value in decimal of the current digit
for (int i = 0; i < number.length; i++) {
int digit = charToDigit(number, i);
digits.add(digit);
}
//Reverse the list
digits = digits.reversed.toList();
int dres = 0;
for (int i = 0; i < digits.length; i++) {
dres += digits[i] * pow(base, i).toInt();
}
res = dres.toString();
break;
}
return res;
}
int charToDigit(String s, int i) {
return isDigit(s, i) ? int.parse(s[i]) : s.codeUnitAt(i) - 55;
}
// https://stackoverflow.com/questions/25872456/dart-what-is-the-fastest-way-to-check-if-a-particular-symbol-in-a-string-is-a-d
bool isDigit(String s, int i) => (s.codeUnitAt(i) ^ 0x30) <= 9;