Fractions in a NumericUpDown/DomainUpDown - c#

Is it possible to display fractions in a NumericUpDown or a DomainUpDown?
I know there are some fonts that have various fraction characters, but I would like to keep my form using Microsoft Sans Serif uniformly.

What do you mean by upto one-tenth.
I have a sample code for you, try if it works for you
nupdwn.Minimum = -10;
nupdwn.Maximum = 10;
nupdwn.Increment = 0.25;
nupdwn.DecimalPlaces = 2;

Microsoft Sans Serif does support fractional characters:
I will try to program a derived NumericUpDown to show fractional values. If it succeeds, i will share the code here...

Here is my Sample-Code for a FractionalUpDown.
Be sure to set DecimalPlaces to your needs.
With Mode, you can choose the formatting of the value:
EMode.Decimal => 2,500.
EMode.Fractional => ⁵⁄₂
EMode.FractionalMixed => 2 ¹⁄₂
EMode.FractionalASCII => 5/2
EMode.FractionalMixedASCII => 2 1/2
Code:
public class FractionalUpDown: NumericUpDown {
//Hide Hexadecimal
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool Hexadecimal {
get { return false; }
set { base.Hexadecimal = false; }
}
private EMode mode;
[DefaultValue(EMode.Fractional)]
public EMode Mode {
get { return mode; }
set {
if (value != mode) {
mode = value;
UpdateEditText();
}
}
}
public enum EMode {
Fractional,
FractionalMixed,
FractionalASCII,
FractionalMixedASCII,
Decimal
}
public FractionalUpDown() {
}
protected override void UpdateEditText() {
if (Mode == EMode.Decimal) {
base.UpdateEditText();
return;
}
double accuracy = Math.Pow(10.0, -(DecimalPlaces + 1));
if (accuracy > 0.1) accuracy = 0.1;
this.Text = FractionToString(DoubleToFraction((double)Value, accuracy), Mode);
}
public struct Fraction {
public Fraction(int n, int d) {
N = n;
D = d;
}
public int N { get; private set; }
public int D { get; private set; }
}
private static readonly char[] numbers = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private static readonly char[] numerators = new char[10] { '⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹' };
private static readonly char[] denumerators = new char[10] { '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉' };
protected string FractionToString(Fraction frac, EMode mode) {
int full = 0;
int n = frac.N;
string result = string.Empty;
bool mixed = mode == EMode.FractionalMixed ||
mode == EMode.FractionalMixedASCII;
bool useFractionalChars = mode == EMode.Fractional ||
mode == EMode.FractionalMixed;
if (mixed && Math.Abs(frac.N) >= frac.D) {
full = frac.N / frac.D;
n = Math.Abs(frac.N % frac.D);
if (full != 0) result = full.ToString();
else if (n == 0) return "0";
}
if (n != 0) {
string fracNtext = n.ToString();
string fracDtext = frac.D.ToString();
if (useFractionalChars) {
for (int i = 0; i < 10; i++) fracNtext = fracNtext.Replace(numbers[i], numerators[i]);
for (int i = 0; i < 10; i++) fracDtext = fracDtext.Replace(numbers[i], denumerators[i]);
} else {
if (full != 0) result += " ";
}
result += fracNtext + '⁄' + fracDtext;
} else {
//Fractional Part == 0/?
if (full == 0) {
if (mixed == true) {
return "0";
} else {
if (useFractionalChars) {
return numerators[0].ToString() + '⁄' + denumerators[1].ToString();
} else {
return numbers[0].ToString() + '⁄' + numbers[1].ToString();
}
}
}
}
return result;
}
//Source: https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions/32903747#32903747
protected Fraction DoubleToFraction(double value, double accuracy) {
if (accuracy <= 0.0 || accuracy >= 1.0) {
throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1.");
}
int sign = Math.Sign(value);
if (sign == -1) {
value = Math.Abs(value);
}
// Accuracy is the maximum relative error; convert to absolute maxError
double maxError = sign == 0 ? accuracy : value * accuracy;
int n = (int)Math.Floor(value);
value -= n;
if (value < maxError) {
return new Fraction(sign * n, 1);
}
if (1 - maxError < value) {
return new Fraction(sign * (n + 1), 1);
}
// The lower fraction is 0/1
int lower_n = 0;
int lower_d = 1;
// The upper fraction is 1/1
int upper_n = 1;
int upper_d = 1;
while (true) {
// The middle fraction is (lower_n + upper_n) / (lower_d + upper_d)
int middle_n = lower_n + upper_n;
int middle_d = lower_d + upper_d;
if (middle_d * (value + maxError) < middle_n) {
// real + error < middle : middle is our new upper
Seek(ref upper_n, ref upper_d, lower_n, lower_d, (un, ud) => (lower_d + ud) * (value + maxError) < (lower_n + un));
upper_n = middle_n;
upper_d = middle_d;
} else if (middle_n < (value - maxError) * middle_d) {
// middle < real - error : middle is our new lower
Seek(ref lower_n, ref lower_d, upper_n, upper_d, (ln, ld) => (ln + upper_n) < (value - maxError) * (ld + upper_d));
lower_n = middle_n;
lower_d = middle_d;
} else {
// Middle is our best fraction
return new Fraction((n * middle_d + middle_n) * sign, middle_d);
}
}
}
/// <summary>
/// Binary seek for the value where f() becomes false.
/// Source: https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions/32903747#32903747
/// </summary>
protected void Seek(ref int a, ref int b, int ainc, int binc, Func<int, int, bool> f) {
a += ainc;
b += binc;
if (f(a, b)) {
int weight = 1;
do {
weight *= 2;
a += ainc * weight;
b += binc * weight;
}
while (f(a, b));
do {
weight /= 2;
int adec = ainc * weight;
int bdec = binc * weight;
if (!f(a - adec, b - bdec)) {
a -= adec;
b -= bdec;
}
}
while (weight > 1);
}
}
}

Related

RSI calculation element by element instead of all at once

The disadvantage of the code below is that it calculates the RSI for all prices at once. What if I have to add a new price? It's going to recalculate everything just because one additional price in the array. It will take longer than if I backup AverageGain/AverageLoss.
public class RSI
{
private readonly int _period;
public RSI(int period)
{
_period = period;
}
public decimal[] Calculate(decimal[] prices)
{
var rsi = new decimal[prices.Length];
decimal gain = 0m;
decimal loss = 0m;
rsi[0] = 0m;
for (int i = 1; i <= _period; ++i)
{
var diff = prices[i] - prices[i - 1];
if (diff >= 0)
{
gain += diff;
}
else
{
loss -= diff;
}
}
decimal avrg = gain / _period;
decimal avrl = loss / _period;
decimal rs = gain / loss;
rsi[_period] = 100m - (100m / (1m + rs));
for (int i = _period + 1; i < prices.Length; ++i)
{
var diff = prices[i] - prices[i - 1];
if (diff >= 0)
{
avrg = ((avrg * (_period - 1)) + diff) / _period;
avrl = (avrl * (_period - 1)) / _period;
}
else
{
avrl = ((avrl * (_period - 1)) - diff) / _period;
avrg = (avrg * (_period - 1)) / _period;
}
rs = avrg / avrl;
rsi[i] = 100m - (100m / (1m + rs));
}
return rsi;
}
}
My idea is to make something that remembers the previous input and calculate the RSI based on it, just like this one. Right now, this code is not working because _period is not involved at all. Those people in that github made it, but I'm still struggling to do it because of all these inherited classes/interfaces. I don't want to implement all of the interfaces/abstract classes. The one I extracted below are enough for me.
// Trying to achieve this:
var candles = _client.GetKlines(bot.Symbol, KlineInterval.OneHour).Data.ToList();
RelativeStrengthIndex rsi = new RelativeStrengthIndex(12);
for (int i = 0; i < candles.Count - 1; i++)
{
var result = rsi.ComputeNextValue(new InputData(candles[i].Close));
Console.WriteLine($"RSI(12) = {result}");
}
// New candle data
var newResult = rsi.ComputeNextValue(new InputData(0.01256m));
Console.WriteLine($"RSI(12) = {newResult}");
public abstract class Indicator
{
public abstract decimal ComputeNextValue(InputData input);
public abstract void Reset();
}
public class InputData
{
public decimal Value { get; private set; }
public InputData(decimal value)
{
Value = value;
}
}
public class RelativeStrengthIndex : Indicator
{
private int _period;
private InputData _previousInput;
public decimal AverageGain { get; private set; }
public decimal AverageLoss { get; private set; }
public RelativeStrengthIndex(int period)
{
_period = period;
}
public override decimal ComputeNextValue(InputData input)
{
if (_previousInput != null && input.Value >= _previousInput.Value)
{
AverageGain = input.Value - _previousInput.Value;
AverageLoss = 0m;
}
else if (_previousInput != null && input.Value < _previousInput.Value)
{
AverageGain = 0m;
AverageLoss = _previousInput.Value - input.Value;
}
_previousInput = input;
if (AverageLoss == 0m)
{
return 100m;
}
var rs = AverageGain / AverageLoss;
return 100m - (100m / (1 + rs));
}
public override void Reset()
{
_previousInput = default;
}
}
I did it myself. If you have any suggestions/improvements, please note them in the comments.
public class RelativeStrengthIndex : Indicator
{
private readonly int _period;
private InputData _previousInput;
private int _index;
private decimal _gain;
private decimal _loss;
private decimal _averageGain;
private decimal _averageLoss;
public RelativeStrengthIndex(int period)
{
_period = period;
_index = 0;
_gain = 0;
_loss = 0;
_averageGain = 0;
_averageLoss = 0;
}
public override decimal ComputeNextValue(InputData input)
{
// Formula: https://stackoverflow.com/questions/38481354/rsi-vs-wilders-rsi-calculation-problems?rq=1
_index++;
if (_previousInput != null)
{
var diff = input.Value - _previousInput.Value;
_previousInput = input;
if (_index <= _period)
{
if (diff >= 0)
{
_totalGain += diff;
}
else
{
_totalLoss -= diff;
}
}
if (_index < _period)
{
return 0;
}
else if (_index == _period)
{
_averageGain = _totalGain / _period;
_averageLoss = _totalLoss / _period;
decimal rs = _averageGain / _averageLoss;
return 100 - (100 / (1 + rs));
}
else // if (_index >= _period + 1)
{
if (diff >= 0)
{
_averageGain = ((_averageGain * (_period - 1)) + diff) / _period;
_averageLoss = (_averageLoss * (_period - 1)) / _period;
}
else
{
_averageGain = (_averageGain * (_period - 1)) / _period;
_averageLoss = ((_averageLoss * (_period - 1)) - diff) / _period;
}
decimal rs = _averageGain / _averageLoss;
return 100 - (100 / (1 + rs));
}
}
_previousInput = input;
return 0;
}
public override void Reset()
{
_previousInput = null;
_index = 0;
_gain = 0;
_loss = 0;
_averageGain = 0;
_averageLoss = 0;
}
}

Adding algebraic X notation

I am trying for the last few hours on how to parse a string with algebric notation.
For example if I have the input:
X+8X-21X+21X+16
The output should be:
9X+16
so far if I tried to see if there exists a number behind X and tried many cases, however I keep on getting an index out of bounds error, and rightufully so. Any suggestions on how to fix it?
int getXPosition= LHSString.IndexOf("X");
int noOfXs = LHSString.Split('X').Length - 1;
int XCount = 0;
if (getXPosition > -1)
{
while (XCount <= noOfXs)
{
int posX = getPositionX(s);
Regex noBeforeX = new Regex(#"\d+");
if ((posX - 1) > -1 && noBeforeX.IsMatch(LHSString.Substring(posX-1,1)))
{
string getNumber = LHSString.Substring(posX-1, 1);
sum += Convert.ToInt32(getNumber);
}
if ((posX - 2) > -1 && noBeforeX.IsMatch(LHSString.Substring(posX - 2, 1)))
{
string gotNumber = LHSString.Substring(posX - 1, 1);
int Number=Convert.ToInt32(gotNumber);
sum += Number;
}
XCount++;
s = s.Substring(posX + 1);
}
}
I would use a more maintainable approach. separate different code parts and use collection of class that will represent the "part" in the algebraic equation.
here is my suggestion:
class Program
{
static void Main(string[] args)
{
string[] operators = { "+", "-", "/", "*" };
string test = "X+8X-21X+21X+16";
int locationcounter = 0;
string part = string.Empty;
List<Part> partsList = new List<Part>();
for (int i = 0; i < test.Length; i++)
{
if (operators.Contains(test[i].ToString()))
{
var operatorbeofore = (partsList.Count <= 0 ? "" : partsList[partsList.Count - 1].OperatorAfter);
partsList.Add(new Part(part, operatorbeofore, test[i].ToString(), locationcounter));
locationcounter++;
part = string.Empty;
}
else
{
part += test[i].ToString();
}
}
// last part that remain
if (part != string.Empty)
{
partsList.Add(new Part(part, partsList[partsList.Count() - 1].OperatorAfter, "", locationcounter++));
}
// output
Console.WriteLine(GetResultOutput(partsList));
Console.ReadLine();
}
private static string GetResultOutput(List<Part> algebraicexpression)
{
// reduce all vars
var vars = algebraicexpression.Where(x => x.IsVar).OrderBy(x => x.locationInEqution).ToList();
int lastVarResult = 0;
int varResult = 0;
if (vars.Count() > 1)
{
lastVarResult = GetCalculation(vars[0].Value, vars[1].Value, vars[1].OperatorBefore);
for (int i = 2; i < vars.Count(); i++)
{
varResult = GetCalculation(lastVarResult, vars[i].Value, vars[i].OperatorBefore);
lastVarResult = varResult;
}
}
else if (vars.Count() == 1)
{
lastVarResult = vars[0].Value;
}
// calculate all "free" numbers
var numbers = algebraicexpression.Where(x => x.IsVar == false).OrderBy(x => x.locationInEqution).ToList();
int lastResult = 0;
int Result = 0;
if (numbers.Count() > 1)
{
lastResult = GetCalculation(vars[0].Value, vars[1].Value, vars[1].OperatorBefore);
for (int i = 2; i < vars.Count(); i++)
{
Result = GetCalculation(lastResult, vars[i].Value, vars[i].OperatorBefore);
lastResult = varResult;
}
}
else if (numbers.Count() == 1)
{
Result = numbers[0].Value;
}
string stringresult = string.Empty;
if (varResult != 0)
{
stringresult = varResult.ToString() + vars[0].Notation;
}
if (Result > 0)
{
stringresult = stringresult + "+" + Result.ToString();
}
else if (Result < 0)
{
stringresult = stringresult + "-" + Result.ToString();
}
return stringresult;
}
private static int GetCalculation(int x, int y, string eqoperator)
{
if (eqoperator == "+")
{
return x + y;
}
else if (eqoperator == "-")
{
return x - y;
}
else if (eqoperator == "*")
{
return x * y;
}
else if (eqoperator == "/")
{
return x / y;
}
else
{
return 0;
}
}
}
class Part
{
public string MyAlgebricPart;
public string OperatorBefore;
public string OperatorAfter;
public int locationInEqution;
public Part(string part, string operatorbefore, string operatorafter, int location)
{
this.MyAlgebricPart = part;
this.OperatorAfter = operatorafter;
this.OperatorBefore = operatorbefore;
this.locationInEqution = location;
}
public int Value
{
get
{
if (MyAlgebricPart.Count() == 1 && Notation != string.Empty)
{
return 1;
}
else
{
string result = new String(MyAlgebricPart.Where(Char.IsDigit).ToArray());
return Convert.ToInt32(result);
}
}
}
public string Notation
{
get
{
var onlyLetters = new String(MyAlgebricPart.Where(Char.IsLetter).ToArray());
if (onlyLetters != "")
{
return onlyLetters[0].ToString();
}
else
{
return string.Empty;
}
}
}
public bool IsVar
{
get
{
if (Notation == string.Empty)
return false;
else
return true;
}
}
}

.NET Stops on sorting and Icompare()

I'm having a problem with sorting and IComparer(). My program stops on it. I'm a beginner with C#.
Here is the part of the code where it stops:
public ArrayList ModelSort()
{
IComparer sorter = new R2SortHelper();
InnerList.Sort(sorter);
return InnerList;
}
private class R2SortHelper : System.Collections.IComparer
{
public int Compare(object x, object y)
{
double m1 = ((Model)x).R2() + ((Model)x).Valid().GetHashCode();
double m2 = ((Model)y).R2() + ((Model)y).Valid().GetHashCode();
if (m1 > m2)
return -1;
else if (m1 < m2)
return 1;
else
return 0;
}
}
Here is an error from console:
Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: 'AMO.EnPI.AddIn.Utilities.ModelCollection+R2SortHelper'.
List of exceptions:
Exception Text
System.ArgumentException: Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: 'AMO.EnPI.AddIn.Utilities.ModelCollection+R2SortHelper'.
at System.Array.SorterObjectArray.DepthLimitedQuickSort(Int32 left, Int32 right, Int32 depthLimit)
at System.Array.SorterObjectArray.DepthLimitedQuickSort(Int32 left, Int32 right, Int32 depthLimit)
at System.Array.Sort(Array keys, Array items, Int32 index, Int32 length, IComparer comparer)
at System.Collections.ArrayList.Sort(Int32 index, Int32 count, IComparer comparer)
at System.Collections.ArrayList.Sort(IComparer comparer)
at AMO.EnPI.AddIn.Utilities.ModelCollection.ModelSort() in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.Utilities\Analytics.cs:line 961
at AMO.EnPI.AddIn.ModelSheet.WriteResultsTable(Int32 n, Boolean top) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ModelSheet.cs:line 146
at AMO.EnPI.AddIn.ModelSheet.Populate() in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ModelSheet.cs:line 60
at AMO.EnPI.AddIn.ThisAddIn.plotEnPI(ListObject LO) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ThisAddIn.cs:line 318
at AMO.EnPI.AddIn.RegressionControl.runFunction(Object sender, EventArgs e) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\RegressionControl.cs:line 817
at AMO.EnPI.AddIn.CO2EmissionControl.btnCalculate_Click(Object sender, EventArgs e) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\CO2EmissionControl.cs:line 148
My model class:
public class Model
{
public int ModelNumber { get; set; }
public double[] Ys { get; set; }
public double[,] Xs { get; set; }
public string[] VariableNames { get; set; }
public double RMSError { get; set; }
public double[] Coefficients { get; set; }
public Model()
{
ModelNumber = 0;
Ys = null;
Xs = null;
VariableNames = null;
RMSError = 0;
Coefficients = null;
}
public Model(int ModelNumber, double[] Ys, double[,] Xs, string[] VariableNames)
{
RMSError = 0;
Coefficients = null;
// run LLS
int info;
double[] c;
alglib.lsfitreport rep;
try
{
alglib.lsfitlinear(Ys, Xsplusone(), out info, out c, out rep);
}
catch
{
throw;
}
Coefficients = c;
RMSError = rep.rmserror;
}
public void Run() //double[] Ys, double[,] Xs, string[] VariableNames)
{
RMSError = 0;
Coefficients = null;
if (Ys != null && Xs != null)
{
// run LLS
int info;
double[] c;
alglib.lsfitreport rep;
try
{
alglib.lsfitlinear(Ys, Xsplusone(), out info, out c, out rep);
}
catch
{
throw;
}
Coefficients = c;
RMSError = rep.rmserror;
}
}
public int N()
{
return Ys.Count();
}
public int df()
{
return N() - k() - 1;
}
public int k()
{
return VariableNames.Count();
}
public double TotalSS()
{
// compute total sum of squares
double ybar = Ys.Average();
double sst = 0;
for (int i = Ys.GetLowerBound(0); i <= Ys.GetUpperBound(0); i++)
{
sst += Math.Pow(Ys[i] - ybar, 2);
}
return sst;
}
public double ResidualSS ()
{
return ( N() * Math.Pow( RMSError, 2));
}
public double R2()
{
return (1 - (ResidualSS() / TotalSS()));
}
public double AdjustedR2()
{
return (1 - (((1 - R2()) * (N() - 1)) / (N() - k() - 1)));
}
public double F()
{
return ( (R2() / k()) / ((1 - R2()) / (N() - k() - 1)));
}
public double ModelPValue()
{
double modelP = 0;
double modelF = F();
if (modelF < 0) modelF = 0;
try
{
modelP = alglib.fcdistribution(N() - df() - 1, df(), modelF);
}
catch (alglib.alglibexception e)
{
}
return modelP;
}
public bool Valid()
{
// Model validity criteria, from the SEP M&V protocol:
// The model p-value must be less than 0.1
// All variables must have p-values less than 0.2
// At least one variable must have a p-value of less than 0.1
// The R2 value must be greater than 0.5
double[] ps = PValues();
bool varsvalid = true;
bool varlowexists = false;
for (int i = 0; i < ps.Count(); i++)
{
if (ps[i] <= Constants.PVALUE_THRESHOLD)
varlowexists = true;
if (ps[i] > Constants.PVALUE_HIGH)
varsvalid = false;
}
if (!varlowexists)
return false;
if (!varsvalid)
return false;
if (ModelPValue() > Constants.PVALUE_THRESHOLD)
return false;
if (R2() < Constants.R2VALUE_MIN)
return false;
return true;
}
public string Formula()
{
string formula = "";
int offset = Coefficients.GetLowerBound(0) - VariableNames.GetLowerBound(0);
for (int i = Coefficients.GetLowerBound(0); i < Coefficients.GetUpperBound(0); i++)
{
formula += "(" + Coefficients[i].ToString("0.0000") + " * " + ExcelHelpers.CreateValidFormulaName(VariableNames[i - offset]) + ") + ";
// formula += "(" + Coefficients[i].ToString() + " * " + ExcelHelpers.CreateValidFormulaName(VariableNames[i - offset]) + ") + ";
}
formula += Coefficients[Coefficients.GetUpperBound(0)].ToString("0.00");
return formula;
}
public double[,] Xsplusone()
{
return DataHelper.arrayAddIdentity(Xs, 0, 1); // add on a column of ones for the intercept
}
public double[] PredictedYs()
{ // compute the predicted ys
double[] yhat = new double[N()];
double[,] xs = Xsplusone();
double[] c = Coefficients;
for (int i = 0; i < N(); i++)
{
yhat[i] = 0;
for (int j = 0; j < k() + 1; j++)
{
yhat[i] += xs[i, j] * c[j];
}
}
return yhat;
}
public double[,] CovarianceMatrix()
{
// compute the coefficient covariance matrix
double[,] twodYs = DataHelper.dbl2DArray(Ys);
double[,] XYs = DataHelper.dblarrayUnion(Xs, twodYs);
double[,] cov;
int info;
alglib.linearmodel lm;
alglib.lrreport rpt;
try
{
alglib.lrbuild(XYs, N(), k(), out info, out lm, out rpt);
cov = rpt.c;
}
catch
{
throw;
}
return cov;
}
public double[] StandardErrors()
{
// compute the x std errors and p-values
double[,] cov = CovarianceMatrix();
double[] se = new double[k()];
if (cov.GetLength(0) > 0 && cov.GetLength(1) > 0)
{
for (int j = 0; j < k(); j++)
{
se[j] = Math.Sqrt(cov[j, j]);
}
}
return se;
}
public double[] PValues()
{
double[] c = Coefficients;
double[,] cov = CovarianceMatrix();
double[] se = StandardErrors();
double[] pv = new double[k()];
if (cov.GetLength(0) > 0 && cov.GetLength(1) > 0)
{
for (int j = 0; j < k(); j++)
{
se[j] = Math.Sqrt(cov[j, j]);
try
{
pv[j] = 2 * (1 - alglib.studenttdistribution(df(), Math.Abs(c[j] / se[j])));
}
catch
{
}
}
}
return pv;
}
public string AICFormula()
{
return "";
}
//Added By Suman for SEP Validation changes
public string[] SEPValidationCheck()
{
string[] sepChk = new string[k()];
for (int cnt = 0; cnt < sepChk.Length; cnt++)
{
if (Valid() == true)
{
sepChk[cnt] = "Pass";
}
else
{
sepChk[cnt] = "Fail";
}
}
return sepChk;
}
}
Here is GetHashCode():
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
My R2():
public double R2()
{
return (1 - (ResidualSS() / TotalSS()));
}
For the majority of types, you can't sort by GetHashCode() since the hash code calculations aren't necessarily going to sort in the same order as the value. You can only sort on GetHashCode() reliably when it is the value itself (such as int), but at that point there isn't any point in getting the hash code since you already have the value. Also you didn't show what R2() and Valid() methods do, so who knows what kind of unholyness is going on in there.
EDIT (OP updated code):
Your GetHashCode() usage is definitely not sortable. Nor is adding a boolean to a double. 5 + 0 vs. 2 + 1 is not going to sort correctly (assuming you want the falses up front?)
Just use ((Model)x).R2() vs ((Model)y).R2() as the comparison, if you want the falses or trues up front, you can add something like:
if (x.Valid && !y.Valid)
return 1;
if (!x.Valid && y.Valid)
return -1;
//then do your R2 comparisons here.
That preamble will cause the non valids to always come first and then sort by R2s. You can reverse if you want to go the other way.
Your .Valid() method is returning boolean, and then you go to find hash code. Is this expected from your code?
Basically, you are doing some double value + boolean.GetHashCode(). Solution would be to not use .Valid() in your right side expression. Check that separately.
private class R2SortHelper : System.Collections.IComparer
{
public int Compare(object x, object y)
{
Model xModel = (Model)x;
Model yModel = (Model)y;
if((Model.Valid()==true) && (yModel.Valid()==true))
{
double m1 = xModel.R2() + xModel.GetHashCode();
double m2 = yModel.R2() + yModel.GetHashCode();
return (m1 > m2) ? -1 : ((m1 < m2) ? 1 :0);
}
return 0;
}
}

I am trying to figure out how to convert roman numerals into integers

I am trying to figure out how to convert roman numerals to integers. This is a portion of my code. When I prompt the user to enter M it shows 1000, but when I prompt the user to enter a roman numeral such as VM, it does not give me 995 but instead 1005. This is because I am telling my program to do just that.
What I am trying to figure out is how I can look ahead and get it to know when it is adding or subtracting roman numerals.
How do I begin to go about doing this?
class Roman
{
public int inprogress = 0;
public Roman(string roman)
{
char temp = 'Z';
int length;
length = roman.Length;
for (int i = 0; i < length; i++)
{
temp = roman[i];
if (temp == 'M')
{
inprogress = inprogress + 1000;
}
if (temp == 'D')
{
inprogress = inprogress + 500;
}
if (temp == 'C')
{
inprogress = inprogress + 100;
}
if (temp == 'L')
{
inprogress = inprogress + 50;
}
if (temp == 'X')
{
inprogress = inprogress + 10;
}
if (temp == 'V')
{
inprogress = inprogress + 5;
}
if (temp == 'I')
{
inprogress = inprogress + 1;
}
}
}
}
the trick to converting roman numerals is to work backwards (from the end of the string) not forwards, makes it a lot easier.
eg, if you have IX
you start with X, = 10
move back 1.... now its I, I is less than X so now subtract off 1 = 9
A reference solution....
public class RomanNumeral
{
public static int ToInt(string s)
{
var last = 0;
return s.Reverse().Select(NumeralValue).Sum(v =>
{
var r = (v >= last)? v : -v;
last = v;
return r;
});
}
private static int NumeralValue(char c)
{
switch (c)
{
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
}
return 0;
}
}
NOTE: this doesn't validate roman numerals, just convert ones that are already valid.
List<Level> levels = new List<Level>();
int[] val = new int[255];
private void Form1_Load(object sender, EventArgs e)
{
val[(byte)'I'] = 1;
val[(byte)'V'] = 5;
val[(byte)'X'] = 10;
val[(byte)'L'] = 50;
val[(byte)'C'] = 100;
val[(byte)'D'] = 500;
val[(byte)'M'] = 1000;
levels.Clear();
levels.Add(new Level('I', 'V', 'X'));
levels.Add(new Level('X', 'L', 'C'));
levels.Add(new Level('C', 'D', 'M'));
}
int fromRoman(string n)
{
n = n.ToUpper();
var result = 0;
var lastDigit = 0;
for (var pos = n.Length - 1; pos >= 0; pos--)
{
var curDigit = val[(byte)n[pos]];
if (curDigit >= lastDigit)
result += curDigit;
else
result -= curDigit;
lastDigit = curDigit;
}
return result;
}
public class Level
{
public Level(char i, char v, char x)
{
this.i = i;
this.x = x;
this.v = v;
}
public char i;
public char v;
public char x;
}
Then Run
int Result = fromRoman("X");
You need to add logic that basically says that if the V is before the M then subtract it. Based on this line here:
if (temp == 'V')
{
inprogress = inprogress + 5;

Convert integer to binary in C#

How to convert an integer number into its binary representation?
I'm using this code:
String input = "8";
String output = Convert.ToInt32(input, 2).ToString();
But it throws an exception:
Could not find any parsable digits
Your example has an integer expressed as a string. Let's say your integer was actually an integer, and you want to take the integer and convert it to a binary string.
int value = 8;
string binary = Convert.ToString(value, 2);
Which returns 1000.
Convert from any classic base to any base in C#
string number = "100";
int fromBase = 16;
int toBase = 10;
string result = Convert.ToString(Convert.ToInt32(number, fromBase), toBase);
// result == "256"
Supported bases are 2, 8, 10 and 16
Very Simple with no extra code, just input, conversion and output.
using System;
namespace _01.Decimal_to_Binary
{
class DecimalToBinary
{
static void Main(string[] args)
{
Console.Write("Decimal: ");
int decimalNumber = int.Parse(Console.ReadLine());
int remainder;
string result = string.Empty;
while (decimalNumber > 0)
{
remainder = decimalNumber % 2;
decimalNumber /= 2;
result = remainder.ToString() + result;
}
Console.WriteLine("Binary: {0}",result);
}
}
}
http://zamirsblog.blogspot.com/2011/10/convert-decimal-to-binary-in-c.html
public string DecimalToBinary(string data)
{
string result = string.Empty;
int rem = 0;
try
{
if (!IsNumeric(data))
error = "Invalid Value - This is not a numeric value";
else
{
int num = int.Parse(data);
while (num > 0)
{
rem = num % 2;
num = num / 2;
result = rem.ToString() + result;
}
}
}
catch (Exception ex)
{
error = ex.Message;
}
return result;
}
primitive way:
public string ToBinary(int n)
{
if (n < 2) return n.ToString();
var divisor = n / 2;
var remainder = n % 2;
return ToBinary(divisor) + remainder;
}
Another alternative but also inline solution using Enumerable and LINQ is:
int number = 25;
string binary = Enumerable.Range(0, (int)Math.Log(number, 2) + 1).Aggregate(string.Empty, (collected, bitshifts) => ((number >> bitshifts) & 1 ) + collected);
Convert.ToInt32(string, base) does not do base conversion into your base. It assumes that the string contains a valid number in the indicated base, and converts to base 10.
So you're getting an error because "8" is not a valid digit in base 2.
String str = "1111";
String Ans = Convert.ToInt32(str, 2).ToString();
Will show 15 (1111 base 2 = 15 base 10)
String str = "f000";
String Ans = Convert.ToInt32(str, 16).ToString();
Will show 61440.
static void convertToBinary(int n)
{
Stack<int> stack = new Stack<int>();
stack.Push(n);
// step 1 : Push the element on the stack
while (n > 1)
{
n = n / 2;
stack.Push(n);
}
// step 2 : Pop the element and print the value
foreach(var val in stack)
{
Console.Write(val % 2);
}
}
I know this answer would look similar to most of the answers already here, but I noticed just about none of them uses a for-loop. This code works, and can be considered simple, in the sense it will work without any special functions, like a ToString() with parameters, and is not too long as well. Maybe some prefer for-loops instead of just while-loop, this may be suitable for them.
public static string ByteConvert (int num)
{
int[] p = new int[8];
string pa = "";
for (int ii = 0; ii<= 7;ii = ii +1)
{
p[7-ii] = num%2;
num = num/2;
}
for (int ii = 0;ii <= 7; ii = ii + 1)
{
pa += p[ii].ToString();
}
return pa;
}
using System;
class Program
{
static void Main(string[] args) {
try {
int i = (int) Convert.ToInt64(args[0]);
Console.WriteLine("\n{0} converted to Binary is {1}\n", i, ToBinary(i));
} catch(Exception e) {
Console.WriteLine("\n{0}\n", e.Message);
}
}
public static string ToBinary(Int64 Decimal) {
// Declare a few variables we're going to need
Int64 BinaryHolder;
char[] BinaryArray;
string BinaryResult = "";
while (Decimal > 0) {
BinaryHolder = Decimal % 2;
BinaryResult += BinaryHolder;
Decimal = Decimal / 2;
}
BinaryArray = BinaryResult.ToCharArray();
Array.Reverse(BinaryArray);
BinaryResult = new string(BinaryArray);
return BinaryResult;
}
}
This function will convert integer to binary in C#:
public static string ToBinary(int N)
{
int d = N;
int q = -1;
int r = -1;
string binNumber = string.Empty;
while (q != 1)
{
r = d % 2;
q = d / 2;
d = q;
binNumber = r.ToString() + binNumber;
}
binNumber = q.ToString() + binNumber;
return binNumber;
}
class Program
{
static void Main(string[] args)
{
var #decimal = 42;
var binaryVal = ToBinary(#decimal, 2);
var binary = "101010";
var decimalVal = ToDecimal(binary, 2);
Console.WriteLine("Binary value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of binary '{0}' is {1}", binary, decimalVal);
Console.WriteLine();
#decimal = 6;
binaryVal = ToBinary(#decimal, 3);
binary = "20";
decimalVal = ToDecimal(binary, 3);
Console.WriteLine("Base3 value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of base3 '{0}' is {1}", binary, decimalVal);
Console.WriteLine();
#decimal = 47;
binaryVal = ToBinary(#decimal, 4);
binary = "233";
decimalVal = ToDecimal(binary, 4);
Console.WriteLine("Base4 value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of base4 '{0}' is {1}", binary, decimalVal);
Console.WriteLine();
#decimal = 99;
binaryVal = ToBinary(#decimal, 5);
binary = "344";
decimalVal = ToDecimal(binary, 5);
Console.WriteLine("Base5 value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of base5 '{0}' is {1}", binary, decimalVal);
Console.WriteLine();
Console.WriteLine("And so forth.. excluding after base 10 (decimal) though :)");
Console.WriteLine();
#decimal = 16;
binaryVal = ToBinary(#decimal, 11);
binary = "b";
decimalVal = ToDecimal(binary, 11);
Console.WriteLine("Hexidecimal value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of Hexidecimal '{0}' is {1}", binary, decimalVal);
Console.WriteLine();
Console.WriteLine("Uh oh.. this aint right :( ... but let's cheat :P");
Console.WriteLine();
#decimal = 11;
binaryVal = Convert.ToString(#decimal, 16);
binary = "b";
decimalVal = Convert.ToInt32(binary, 16);
Console.WriteLine("Hexidecimal value of decimal {0} is '{1}'", #decimal, binaryVal);
Console.WriteLine("Decimal value of Hexidecimal '{0}' is {1}", binary, decimalVal);
Console.ReadLine();
}
static string ToBinary(decimal number, int #base)
{
var round = 0;
var reverseBinary = string.Empty;
while (number > 0)
{
var remainder = number % #base;
reverseBinary += remainder;
round = (int)(number / #base);
number = round;
}
var binaryArray = reverseBinary.ToCharArray();
Array.Reverse(binaryArray);
var binary = new string(binaryArray);
return binary;
}
static double ToDecimal(string binary, int #base)
{
var val = 0d;
if (!binary.All(char.IsNumber))
return 0d;
for (int i = 0; i < binary.Length; i++)
{
var #char = Convert.ToDouble(binary[i].ToString());
var pow = (binary.Length - 1) - i;
val += Math.Pow(#base, pow) * #char;
}
return val;
}
}
Learning sources:
Everything you need to know about binary
including algorithm to convert decimal to binary
class Program{
static void Main(string[] args){
try{
int i = (int)Convert.ToInt64(args[0]);
Console.WriteLine("\n{0} converted to Binary is {1}\n",i,ToBinary(i));
}catch(Exception e){
Console.WriteLine("\n{0}\n",e.Message);
}
}//end Main
public static string ToBinary(Int64 Decimal)
{
// Declare a few variables we're going to need
Int64 BinaryHolder;
char[] BinaryArray;
string BinaryResult = "";
while (Decimal > 0)
{
BinaryHolder = Decimal % 2;
BinaryResult += BinaryHolder;
Decimal = Decimal / 2;
}
// The algoritm gives us the binary number in reverse order (mirrored)
// We store it in an array so that we can reverse it back to normal
BinaryArray = BinaryResult.ToCharArray();
Array.Reverse(BinaryArray);
BinaryResult = new string(BinaryArray);
return BinaryResult;
}
}//end class Program
BCL provided Convert.ToString(n, 2) is good, but in case you need an alternate implementation which is few ticks faster than BCL provided one.
Following custom implementation works for all integers(-ve and +ve).
Original source taken from https://davidsekar.com/algorithms/csharp-program-to-convert-decimal-to-binary
static string ToBinary(int n)
{
int j = 0;
char[] output = new char[32];
if (n == 0)
output[j++] = '0';
else
{
int checkBit = 1 << 30;
bool skipInitialZeros = true;
// Check the sign bit separately, as 1<<31 will cause
// +ve integer overflow
if ((n & int.MinValue) == int.MinValue)
{
output[j++] = '1';
skipInitialZeros = false;
}
for (int i = 0; i < 31; i++, checkBit >>= 1)
{
if ((n & checkBit) == 0)
{
if (skipInitialZeros)
continue;
else
output[j++] = '0';
}
else
{
skipInitialZeros = false;
output[j++] = '1';
}
}
}
return new string(output, 0, j);
}
Above code is my implementation. So, I'm eager to hear any feedback :)
// I use this function
public static string ToBinary(long number)
{
string digit = Convert.ToString(number % 2);
if (number >= 2)
{
long remaining = number / 2;
string remainingString = ToBinary(remaining);
return remainingString + digit;
}
return digit;
}
static void Main(string[] args)
{
Console.WriteLine("Enter number for converting to binary numerical system!");
int num = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[16];
//for positive integers
if (num > 0)
{
for (int i = 0; i < 16; i++)
{
if (num > 0)
{
if ((num % 2) == 0)
{
num = num / 2;
arr[16 - (i + 1)] = 0;
}
else if ((num % 2) != 0)
{
num = num / 2;
arr[16 - (i + 1)] = 1;
}
}
}
for (int y = 0; y < 16; y++)
{
Console.Write(arr[y]);
}
Console.ReadLine();
}
//for negative integers
else if (num < 0)
{
num = (num + 1) * -1;
for (int i = 0; i < 16; i++)
{
if (num > 0)
{
if ((num % 2) == 0)
{
num = num / 2;
arr[16 - (i + 1)] = 0;
}
else if ((num % 2) != 0)
{
num = num / 2;
arr[16 - (i + 1)] = 1;
}
}
}
for (int y = 0; y < 16; y++)
{
if (arr[y] != 0)
{
arr[y] = 0;
}
else
{
arr[y] = 1;
}
Console.Write(arr[y]);
}
Console.ReadLine();
}
}
This might be helpful if you want a concise function that you can call from your main method, inside your class. You may still need to call int.Parse(toBinary(someint)) if you require a number instead of a string but I find this method work pretty well. Additionally, this can be adjusted to use a for loop instead of a do-while if you'd prefer.
public static string toBinary(int base10)
{
string binary = "";
do {
binary = (base10 % 2) + binary;
base10 /= 2;
}
while (base10 > 0);
return binary;
}
toBinary(10) returns the string "1010".
I came across this problem in a coding challenge where you have to convert 32 digit decimal to binary and find the possible combination of the substring.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
public static void Main()
{
int numberofinputs = int.Parse(Console.ReadLine());
List<BigInteger> inputdecimal = new List<BigInteger>();
List<string> outputBinary = new List<string>();
for (int i = 0; i < numberofinputs; i++)
{
inputdecimal.Add(BigInteger.Parse(Console.ReadLine(), CultureInfo.InvariantCulture));
}
//processing begins
foreach (var n in inputdecimal)
{
string binary = (binaryconveter(n));
subString(binary, binary.Length);
}
foreach (var item in outputBinary)
{
Console.WriteLine(item);
}
string binaryconveter(BigInteger n)
{
int i;
StringBuilder output = new StringBuilder();
for (i = 0; n > 0; i++)
{
output = output.Append(n % 2);
n = n / 2;
}
return output.ToString();
}
void subString(string str, int n)
{
int zeroodds = 0;
int oneodds = 0;
for (int len = 1; len <= n; len++)
{
for (int i = 0; i <= n - len; i++)
{
int j = i + len - 1;
string substring = "";
for (int k = i; k <= j; k++)
{
substring = String.Concat(substring, str[k]);
}
var resultofstringanalysis = stringanalysis(substring);
if (resultofstringanalysis.Equals("both are odd"))
{
++zeroodds;
++oneodds;
}
else if (resultofstringanalysis.Equals("zeroes are odd"))
{
++zeroodds;
}
else if (resultofstringanalysis.Equals("ones are odd"))
{
++oneodds;
}
}
}
string outputtest = String.Concat(zeroodds.ToString(), ' ', oneodds.ToString());
outputBinary.Add(outputtest);
}
string stringanalysis(string str)
{
int n = str.Length;
int nofZeros = 0;
int nofOnes = 0;
for (int i = 0; i < n; i++)
{
if (str[i] == '0')
{
++nofZeros;
}
if (str[i] == '1')
{
++nofOnes;
}
}
if ((nofZeros != 0 && nofZeros % 2 != 0) && (nofOnes != 0 && nofOnes % 2 != 0))
{
return "both are odd";
}
else if (nofZeros != 0 && nofZeros % 2 != 0)
{
return "zeroes are odd";
}
else if (nofOnes != 0 && nofOnes % 2 != 0)
{
return "ones are odd";
}
else
{
return "nothing";
}
}
Console.ReadKey();
}
}
}
int x=550;
string s=" ";
string y=" ";
while (x>0)
{
s += x%2;
x=x/2;
}
Console.WriteLine(Reverse(s));
}
public static string Reverse( string s )
{
char[] charArray = s.ToCharArray();
Array.Reverse( charArray );
return new string( charArray );
}
This was a interesting read i was looking for a quick copy paste.
I knew i had done this before long ago with bitmath differently.
Here was my take on it.
// i had this as a extension method in a static class (this int inValue);
public static string ToBinaryString(int inValue)
{
string result = "";
for (int bitIndexToTest = 0; bitIndexToTest < 32; bitIndexToTest++)
result += ((inValue & (1 << (bitIndexToTest))) > 0) ? '1' : '0';
return result;
}
You could stick spacing in there with a bit of modulos in the loop.
// little bit of spacing
if (((bitIndexToTest + 1) % spaceEvery) == 0)
result += ' ';
You could probably use or pass in a stringbuilder and append or index directly to avoid deallocations and also get around the use of += this way;
var b = Convert.ToString(i,2).PadLeft(32,'0').ToCharArray().Reverse().ToArray();
Just one line for 8 bit
Console.WriteLine(Convert.ToString(n, 2).PadLeft(8, '0'));
where n is the number

Categories

Resources