unity freezes when my loop activates, and displays no error message - c#

ok, so i am making a script for my game that generates the composition of a silicate planet. it is not great code, as i am pretty new to coding, but here it is:
using UnityEngine;
public class silicateComposition : MonoBehaviour
{
public GameObject noise;
public int silicone;
public int ironOxide;
public int iron;
public int oxygen;
public int aluminium;
public int calcium;
public int sodium;
public int potassium;
public int magnesium;
// Start is called before the first frame update
void Start()
{
Debug.Log("was run");
int seed = noise.GetComponent<mapGenerator>().seed;
Debug.Log("go2");
ironOxide = seed / 15;
iron = seed / 100;
oxygen = seed / 13;
aluminium = seed / 132;
calcium = seed / 104;
sodium = seed / 115;
potassium = seed / 193;
magnesium = seed / 294;
int total = iron + ironOxide + oxygen + aluminium + calcium + sodium + potassium + magnesium;
Debug.Log(ironOxide);
Debug.Log(iron);
Debug.Log(oxygen);
Debug.Log(aluminium);
Debug.Log(calcium);
Debug.Log(sodium);
Debug.Log(potassium);
Debug.Log(magnesium);
Debug.Log(total);
if (total > 85)
{
int t = total - 85;
total = total - t;
int iod = ironOxide.ToString().Length;
int id = iron.ToString().Length;
int od = oxygen.ToString().Length;
int ad = aluminium.ToString().Length;
int sd = sodium.ToString().Length;
int pd = potassium.ToString().Length;
int md = magnesium.ToString().Length;
int cd = calcium.ToString().Length;
Debug.Log(iod);
if (iod >= 2)
{
int iod2 = iod;
int temp = 0;
while (iod > 2)
{
iod = iod - 1;
temp = temp + 1;
}
iod = temp;
int tens = 1000000;
temp = 0;
while (tens.ToString().Length > iod)
{
tens = tens / 10;
}
if (tens = 1)
{
tens = 10;
}
ironOxide = ironOxide / tens;
}
silicone = 100 - total;
if (silicone < 0)
{
silicone = 0;
}
}
}
}
so basically it generates a random percentage based on real life proportions and a seed. Also i have only coded the iron Oxide loop, so I can figure out how to do it before i do it with every element.
It does work, until it hits the if total is above 85 if statement. then unity just freezes. I do not understand why, as I have poured over the code for 2 days now and I'm losing my sanity. thank you for any help.

while (tens.ToString().Length > iod)
If iod is 0 or less, the loop will never terminate.
Also, if (tens = 1) should be if (tens == 1).

Related

blockcopy method 3D array

I am working on a project here where I need to have a rolling average of a 2D array of numbers. The rolling average should average across a rolling "window" size of 8. I have a simple example here to demonstrate, but the idea is that with each new 2D array (a new data scan), that array will be copied into the rolling buffer that I have set up as a 3D array where the 3rd dimension is of size of the rolling window. With the current code I have below, I'm not getting the output I expect. To check if its working, I am just printing out the same position in each 2D scan across all scans of the rolling buffer, but I am not getting what I expect and I'm struggling to find issue in the code. Am I even going about this correctly? Thanks for any help. output attached below.
I would expect an output that looks like:
0 (nextline)
1 | 0 (nextline)
2 | 1 | 0 (nextline)
3 | 2 | 1 | 0 (nextline)
and so on ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlockCopySample
{
class Program
{
static void Main(string[] args)
{
RollingAverager RA = new RollingAverager();
for (int i = 0; i < 25; i++)
{
RA.addValue(i);
RA.PrintBuffer();
System.Threading.Thread.Sleep(1000);
}
}
}
class RollingAverager
{
const int INT_SIZE = 4;
const int DOUBLE_SIZE = 8;
const int BUFFER_LENGTH = 8;
const int SCAN_ROW_SIZE = 3;
const int SCAN_COLUMN_SIZE = 4;
//int scan_value_block_size = SCAN_ROW_SIZE * SCAN_COLUMN_SIZE * DOUBLE_SIZE;
int scan_value_block_size=0;
double[,] array_CurrentScan = null;
double[,,] array_FullBuffer = null;
double total = 0;
int numLoaded = 0;
public double Average { get; set; }
public RollingAverager()
{
array_CurrentScan = new double[SCAN_ROW_SIZE, SCAN_COLUMN_SIZE];
array_FullBuffer = new double[SCAN_ROW_SIZE, SCAN_COLUMN_SIZE, BUFFER_LENGTH];
scan_value_block_size = Buffer.ByteLength(array_CurrentScan);
}
//public void addValue(int newVal)
public void addValue(int index)
{
//Console.Write("here" + index.ToString() + "\n");
for (int j = 0; j < SCAN_ROW_SIZE; j++)
{
for (int k = 0; k < SCAN_COLUMN_SIZE; k++)
{
array_CurrentScan[j, k] = (double) index + j + k;
}
}
//Console.Write("here 1\n");
if (numLoaded == 0)
{
numLoaded++;
Console.Write("here 2\n");
}
else if(numLoaded > 0 && numLoaded < BUFFER_LENGTH)
{
//shift all buffer scans by 1 index to allow for new data to be copied into 0 index
Buffer.BlockCopy(array_FullBuffer, 0 * scan_value_block_size, array_FullBuffer, 1 * scan_value_block_size, numLoaded * scan_value_block_size);
Console.Write("here 3\n");
numLoaded++;
}
else
{
//shift all buffer scans by 1 index to allow for new data to be copied into 0 index
Buffer.BlockCopy(array_FullBuffer, 0 * scan_value_block_size, array_FullBuffer, 1 * scan_value_block_size, (BUFFER_LENGTH - 1) * scan_value_block_size);
Console.Write("here 4\n");
}
//Copy new data into buffer at index 0
Buffer.BlockCopy(array_CurrentScan, 0 * scan_value_block_size, array_FullBuffer, 0 * scan_value_block_size, scan_value_block_size);
//Average = total / numLoaded;
}
public void PrintBuffer()
{
//Console.Write("|");
//Console.Write(total.ToString() + "\n");
for (int i = 0; i < numLoaded; i++)
{
//total += array_FullBuffer[0,3,i];
Console.Write(array_FullBuffer[0, 0, 0].ToString() + " | ");
}
Console.Write("\n");
//Console.WriteLine(" Average = " + Average.ToString());
}
}
}

How to return a value from Cudafy c# GPU calculation?

My Issue
Hey, so I'm making this simple calculation to find the sum of sins between 0 and 100 degrees(as I use it as a benchmark for my systems), the calculation isn't the problem my issue is that I am new to Cudafy and I am unsure on how to properly pass in and return values so that it can be printed off here is my code:
Code
public const int N = 33 * 1024;
public const int threadsPerBlock = 256;
public const int blocksPerGrid = 32;
public static void Main()
{
Stopwatch watch = new Stopwatch();
watch.Start();
string Text = "";
int iterations = 1000000;
CudafyModule km = CudafyTranslator.Cudafy();
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
double[] dev_Value = gpu.Allocate<double>();
gpu.Launch(blocksPerGrid, threadsPerBlock).SumOfSines(iterations,dev_Value);
double Value;
gpu.CopyFromDevice(dev_Value, out Value);
watch.Stop();
Text = watch.Elapsed.TotalSeconds.ToString();
Console.WriteLine("The process took a total of: " + Text + " Seconds");
Console.WriteLine(Value);
Console.Read();
gpu.FreeAll();
}
[Cudafy]
public static void SumOfSines(GThread thread,int iterations,double [] Value)
{
double total = new double();
double degAsRad = Math.PI / 180.0;
for (int i = 0; i < iterations; i++)
{
total = 0.0;
for (int z = 1; z < 101; z++)
{
double angle = (double)z * degAsRad;
total += Math.Sin(angle);
}
}
Value[0] = total;
}
The value that I am trying to extract from the CUDAfy part is the total and then print it off aswell as printing the time for the benchmarking. If anyone could post advice it would be very much appreciated (also any suggestions for making rid of any useless lines or unefficient pieces would also be good).
Doesn't matter I found the answer but I'll post it here:
public const int N = 33 * 1024;
public const int threadsPerBlock = 256;
public const int blocksPerGrid = 32;
public static void Main()
{
Stopwatch watch = new Stopwatch();
watch.Start();
CudafyModule km = CudafyTranslator.Cudafy();
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
string Text = "";
int iterations = 1000000;
double Value;
double[] dev_Value = gpu.Allocate<double>(iterations * sizeof(double));
gpu.Launch(blocksPerGrid, threadsPerBlock).SumOfSines(iterations, dev_Value);
gpu.CopyFromDevice(dev_Value, out Value);
watch.Stop();
Text = watch.Elapsed.TotalSeconds.ToString();
Console.WriteLine("The process took a total of: " + Text + " Seconds");
Console.WriteLine(Value);
Console.Read();
gpu.FreeAll();
}
[Cudafy]
public static void SumOfSines(GThread thread, int _iterations, double[] Value)
{
int threadID = thread.threadIdx.x + thread.blockIdx.x * thread.blockDim.x;
int numThreads = thread.blockDim.x * thread.gridDim.x;
if (threadID < _iterations){
for (int i = threadID; i < _iterations; i += numThreads)
{
double _degAsRad = Math.PI / 180;
Value[i] = 0.0;
for (int a = 0; a < 100; a++)
{
double angle = (double)a * _degAsRad;
Value[i] += Math.Sin(angle);
}
}
}
}
-Jack

Odd C# behavior

I'm a hobby programmer.
I tried to ask this question earlier on a very unstructured way (Sorry again), now I try to ask on the proper way.
I wrote the following code that seems to work unreliably.
The code was written like this for several reasons. I know it's messy but it should still work. To explain why I wrote it like this would mean that I need to explain several weeks' of work that is quite extensive. Please accept that this is at least the least worse option I could figure out. In the below sample I removed all sections of the code that are not needed to reproduce the error.
What this program does in a nutshell:
The purpose is to check a large number of parameter combinations for a program that receives streaming data. I simulate the original process to test parameter combinations.
First data is read from files that represents recorded streaming data.
Then the data is aggregated.
Then I build a list of parameters to test for.
Finally I run the code for each parameter combination in parallel.
Inside the parallel part I calculate a financial indicator called the bollinger bands. This is a moving average with adding +/- standard deviation. This means the upper line and the lower line should only be equal when variable bBandDelta = 0. However sometimes it happens that CandleList[slot, w][ctr].bollingerUp is equal to CandleList[slot, w][ctr].bollingerDown even when bBandDelta is not 0.
As a result I don't understand how can line 277 kick in. It seems that sometimes the program fails to write to the CandleList[slot, w][ctr]. However this should not be possible because (1) I lock the list and (2) I use ConcurrentBag. Could I have some help please?
Source files are here.
The code is:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace Justfortest
{
class tick : IComparable<tick> //Data element to represent a tick
{
public string disp_name; //ticker ID
public DateTime? trd_date; //trade date
public TimeSpan? trdtim_1; //trade time
public decimal trdprc_1; //price
public int? trdvol_1; //tick volume
public int CompareTo(tick other)
{
if (this.trdprc_1 == other.trdprc_1)
{
return other.trdprc_1.CompareTo(this.trdprc_1); //Return the later item
}
return this.trdprc_1.CompareTo(other.trdprc_1); //Return the earlier item
}
}
class candle : IComparable<candle> //Data element to represent a candle and all chart data calculated on candle level
{
public int id = 0;
public DateTime? openDate;
public TimeSpan? openTime;
public DateTime? closeDate;
public TimeSpan? closeTime;
public decimal open = 0;
public decimal high = 0;
public decimal low = 0;
public decimal close = 0;
public int? volume = 0;
public decimal totalPrice = 0;
public decimal bollingerUp = 0; //Bollinger upper line
public decimal bollingerDown = 0; //Bollinger below line
public int CompareTo(candle other)
{
if (totalPrice == other.totalPrice)
{
return other.totalPrice.CompareTo(totalPrice); //Return the later item
}
return totalPrice.CompareTo(other.totalPrice); //Return the earlier item
}
}
class param : IComparable<param> //Data element represent a trade event signal
{
public int par1;
public int bollPar;
public int par2;
public int par3;
public int par4;
public int par5;
public int par6;
public decimal par7;
public decimal par8;
public decimal par9;
public decimal par10;
int IComparable<param>.CompareTo(param other)
{
throw new NotImplementedException();
}
}
class programCLass
{
void myProgram()
{
Console.WriteLine("Hello");
Console.WindowWidth = 180;
string[] sources = new string[]
{
#"C:\test\source\sourceW1.csv",
#"C:\test\source\sourceW2.csv",
};
List<candle>[] sourceCandleList = new List<candle>[sources.Count()];
List<param> paramList = new List<param>(10000000);
var csvAnalyzer = new StringBuilder();
{
List<tick>[] updatelist = new List<tick>[sources.Count()];
Console.WriteLine("START LOAD");
for (var i = 0; i < sources.Count(); i++)
{
var file = sources[i];
updatelist[i] = new List<tick>();
// ---------- Read CSV file ----------
var reader = new StreamReader(File.OpenRead(file));
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
tick update = new tick();
update.disp_name = values[0].ToString();
update.trd_date = Convert.ToDateTime(values[1]);
update.trdtim_1 = TimeSpan.Parse(values[2]);
update.trdprc_1 = Convert.ToDecimal(values[3]);
update.trdvol_1 = Convert.ToInt32(values[4]);
updatelist[i].Add(update);
}
Console.WriteLine(i);
}
Console.WriteLine("END LOAD"); // All files are in the memory
// Aggreagate
Console.WriteLine("AGGREGATE START");
int tickAggr = 500;
for (var w = 0; w < sources.Count(); w++)
{
sourceCandleList[w] = new List<candle>();
List<tick> FuturesList = new List<tick>();
foreach (var update in updatelist[w])
{
tick t = new tick();
t.disp_name = update.disp_name.ToString();
t.trd_date = update.trd_date;
t.trdtim_1 = update.trdtim_1;
t.trdprc_1 = Convert.ToDecimal(update.trdprc_1);
t.trdvol_1 = update.trdvol_1;
// Add new tick to the list
FuturesList.Add(t);
if (FuturesList.Count == Math.Truncate(FuturesList.Count / (decimal)tickAggr) * tickAggr)
{
candle c = new candle();
c.openDate = FuturesList[FuturesList.Count - tickAggr].trd_date;
c.openTime = FuturesList[FuturesList.Count - tickAggr].trdtim_1;
c.closeDate = FuturesList.Last().trd_date;
c.closeTime = FuturesList.Last().trdtim_1;
c.open = FuturesList[FuturesList.Count - tickAggr].trdprc_1;
c.high = FuturesList.GetRange(FuturesList.Count - tickAggr, tickAggr).Max().trdprc_1;
c.low = FuturesList.GetRange(FuturesList.Count - tickAggr, tickAggr).Min().trdprc_1;
c.close = FuturesList.Last().trdprc_1;
c.volume = FuturesList.GetRange(FuturesList.Count - tickAggr, tickAggr).Sum(tick => tick.trdvol_1);
c.totalPrice = (c.open + c.high + c.low + c.close) / 4;
sourceCandleList[w].Add(c);
if (sourceCandleList[w].Count == 1)
{
c.id = 0;
}
else
{
c.id = sourceCandleList[w][sourceCandleList[w].Count - 2].id + 1;
}
}
}
FuturesList.Clear();
}
Console.WriteLine("AGGREGATE END");
for (var i = 0; i < sources.Count(); i++)
{
updatelist[i].Clear();
}
}
Console.WriteLine("BUILD PARAMLIST");
for (int par1 = 8; par1 <= 20; par1 += 4) // parameter deployed
{
for (int bollPar = 10; bollPar <= 25; bollPar += 5) // parameter deployed
{
for (int par2 = 6; par2 <= 18; par2 += 4) // parameter deployed
{
for (int par3 = 14; par3 <= 20; par3 += 3) // parameter deployed
{
for (int par4 = 10; par4 <= 20; par4 += 5) // parameter deployed
{
for (int par5 = 4; par5 <= 10; par5 += 2) // parameter deployed
{
for (int par6 = 5; par6 <= 30; par6 += 5)
{
for (decimal par7 = 1.0005M; par7 <= 1.002M; par7 += 0.0005M)
{
for (decimal par8 = 1.002M; par8 <= 1.0048M; par8 += 0.0007M)
{
for (decimal par9 = 0.2M; par9 <= 0.5M; par9 += 0.1M)
{
for (decimal par10 = 0.5M; par10 <= 2; par10 += 0.5M)
{
param p = new param();
p.par1 = par1;
p.bollPar = bollPar;
p.par2 = par2;
p.par3 = par3;
p.par4 = par4;
p.par5 = par5;
p.par6 = par6;
p.par7 = par7;
p.par8 = par8;
p.par9 = par9;
p.par10 = par10;
paramList.Add(p);
}
}
}
}
}
}
}
}
}
}
}
Console.WriteLine("END BUILD PARAMLIST, scenarios to test:{0}", paramList.Count);
var sourceCount = sources.Count();
sources = null;
Console.WriteLine("Start building pools");
int maxThreads = 64;
ConcurrentBag<int> pool = new ConcurrentBag<int>();
List<candle>[,] CandleList = new List<candle>[maxThreads, sourceCount];
for (int i = 0; i <= maxThreads - 1; i++)
{
pool.Add(i);
for (int w = 0; w <= sourceCount - 1; w++)
{
CandleList[i, w] = sourceCandleList[w].ConvertAll(p => p);
}
}
Console.WriteLine("End building pools");
int pItemsProcessed = 0;
Parallel.ForEach(paramList,
new ParallelOptions { MaxDegreeOfParallelism = maxThreads },
p =>
{
int slot = 1000;
while (!pool.TryTake(out slot));
var bollPar = p.bollPar;
decimal bollingerMiddle = 0;
double bBandDeltaX = 0;
for (var w = 0; w < sourceCount; w++)
{
lock (CandleList[slot, w])
{
for (var ctr = 0; ctr < CandleList[slot, w].Count; ctr++)
{
CandleList[slot, w][ctr].bollingerUp = 0; //Bollinger upper line
CandleList[slot, w][ctr].bollingerDown = 0; //Bollinger below line
//Bollinger Bands Calculation
if (ctr + 1 >= bollPar)
{
bollingerMiddle = 0;
bBandDeltaX = 0;
for (int i = 0; i <= bollPar - 1; i++)
{
bollingerMiddle = bollingerMiddle + CandleList[slot, w][ctr - i].totalPrice;
}
bollingerMiddle = bollingerMiddle / bollPar; //average
for (int i = 0; i <= bollPar - 1; i++)
{
bBandDeltaX = bBandDeltaX + (double)Math.Pow(System.Convert.ToDouble(CandleList[slot, w][ctr - i].totalPrice) - System.Convert.ToDouble(bollingerMiddle), 2);
}
bBandDeltaX = bBandDeltaX / bollPar;
decimal bBandDelta = (decimal)Math.Sqrt(System.Convert.ToDouble(bBandDeltaX));
CandleList[slot, w][ctr].bollingerUp = bollingerMiddle + 2 * bBandDelta;
CandleList[slot, w][ctr].bollingerDown = bollingerMiddle - 2 * bBandDelta;
if (CandleList[slot, w][ctr].bollingerUp == CandleList[slot, w][ctr].bollingerDown)
{
Console.WriteLine("?! Items processed=" + pItemsProcessed + " bollPar=" + bollPar + " ctr=" + ctr + " bollingerMiddle=" + bollingerMiddle + " bBandDeltaX=" + bBandDeltaX + " bBandDelta=" + bBandDelta + " bollingerUp=" + CandleList[slot, w][ctr].bollingerUp + " bollingerDown=" + CandleList[slot, w][ctr].bollingerDown);
}
}
// REMOVED Further calculations happen here
}
// REMOVED Some evaluations happen here
}
}
// REMOVED Some more evaluations happen here
Interlocked.Increment(ref pItemsProcessed);
pool.Add(slot);
});
}
static void Main(string[] args)
{
var P = new programCLass();
P.myProgram();
}
}
}

C# Make a sum with two random numbers but it must equal the users input

I was wondering if it is possible to make a sum from a user input int but the sum must be radom every time.
This is the code that I made :
public static string genSum(int askedNumber)
{
string outputStr = null;
bool switchOneTwo = false;
int neededSum = 0;
int intOne = 0;
int intTwo = 0;
while (askedNumber != neededSum)
{
if (switchOneTwo == true)
{
intOne += 1;
switchOneTwo = false;
}
else
{
intTwo += 1;
switchOneTwo = true;
}
neededSum = intOne + intTwo;
if (neededSum == askedNumber)
{
if (neededSum >= 4)
{
Random randomInt = new Random();
int tmpIntOne = intOne;
int tmpIntTwo = intTwo;
int method;
//For now only one method
method = randomInt.Next(1, 1);
if (method == 1)
{
tmpIntOne = tmpIntOne / 2;
tmpIntTwo = (tmpIntTwo * 2) - tmpIntOne;
}
intOne = tmpIntOne;
intTwo = tmpIntTwo;
}
outputStr = "(" + intOne.ToString() + "+" + intTwo.ToString() + ")";
return outputStr;
}
}
return outputStr;
}
so what I want is that if a user eneters a number for example 20 it will then make a sum :
User enters 20 and presses GO! :
Result :
10 + 10 = 20
12 + 8 = 20
5 + 15 = 20
1 + 19 = 20
3 + 17 = 20
User enters 500 and presses GO! :
Result :
9 + 491 = 500
263 + 237 = 500
300 + 200 = 500
250 + 250 = 500
109 + 391 = 500
Create a random number less than the input and the other one will be User-YourRandom
void Foo(int userNumber)
{
Random r = new Random();
int firstNumber = r.Next(userNumber - 1);
int secondNumber = userNumber - firstNumber;
}
You can extend this to support negatives also.
edit getting true randoms
as I4V points out, if you put this in a loop you might get same set of numbers, so instead of calling Random you can use this approach:
void Foo(int userNumber)
{
int userNumber = 500;
for (int i = 0; i < 10; i++ )
{
int firstNumber = Next(0, userNumber - 1);
int secondNumber = userNumber - firstNumber;
Console.WriteLine(firstNumber + "+" + secondNumber);
}
}
internal static int RandomExt(int min, int max)
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buffer = new byte[4];
rng.GetBytes(buffer);
int result = BitConverter.ToInt32(buffer, 0);
return new Random(result).Next(min, max);
}
foreach (var s in genSum(500).Take(5))
{
Console.WriteLine(s);
}
public static IEnumerable<string> genSum(int askedNumber)
{
Random r = new Random();
while (true)
{
var i = r.Next(0, askedNumber);
yield return i + "+" + (askedNumber - i);
}
}

Change calculator

i have a tusk where i have been asked to write a program that calculate change to be given to a customer after a cash transaction, and determines the number of bank notes and coins in each denomination.
the user has to put in the cost of goods and the amount received from the customer.
I must have a class with a method that accepts decimal arguments, Cost and Chashreceived, plus integer arguments for: Hunderds, Fifties, Twenties, Tens, Fives, Twos, Ones, 50c, 10c, 5c, 2c and 1c.
i substract Cost from and the Cashreceived and calculate the exact number of notes and coins required to be returned as change.
I have tried it but it become problematic when i have to put in the coins.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChangeCalculator
{
class Program
{
static void Main(string[] args)
{
clsCash Money = new clsCash();
clsCash Paid = new clsCash();
Console.WriteLine("What is the cost of the goods?");
Money.Cost = Convert.ToDecimal(Console.ReadLine());
Console.WriteLine("How much was recived?");
Paid.CashRecieved = Convert.ToDecimal(Console.ReadLine());
Money.GetChange(Money.Cost, Paid.CashRecieved);
Console.Read();
}
}
class clsCash
{
private decimal cost;
private decimal cashRecieved;
public decimal Cost
{
get
{
return cost;
}
set
{
cost = value;
}
}
public decimal CashRecieved
{
get
{
return cashRecieved;
}
set
{
cashRecieved = value;
}
}
public void GetChange(decimal Cost, decimal CashRecieved)
{
decimal change = CashRecieved - Cost;
int hundreds = 0;
int fifty = 0;
int twenty = 0;
int ten = 0;
int five = 0;
int two = 0;
int one = 0;
int centsfifty = 0;
int centsten = 0;
int centsfive = 0;
int centstwo = 0;
int centsone = 0;
do
{
if (change >= 100)
{
hundreds = (int)change / 100;
change = (int)change % 100;
} //while (change > 0);
else if (change >= 50)
{
fifty = (int)change / 50;
change = change % 50;
}
else if (change >= 20)
{
twenty = (int)change / 20;
change = change % 20;
}
else if (change >= 10)
{
ten = (int)change / 10;
change = change % 10;
}
else if (change >= 5)
{
five = (int)change / 5;
change = change % 5;
}
else if (change >= 2)
{
two = (int)change / 2;
change = change % 2;
}
else if (change >= 1)
{
one = (int)change / 1;
change = change % 1;
}
else if (change > 1)
{
decimal fhu = change / 0.5m;
centsfifty = (int)fhu;
change = change % 0.5m;
Console.WriteLine("YOUR CHANGE IS:");
}
} while (change >= 0);
Console.WriteLine("YOUR CHANGE IS:");
Console.WriteLine("---------------");
Console.WriteLine("HUNDREDS RANDS \t: {0}", hundreds);
Console.WriteLine("FIFTY RANDS \t: {0}", fifty);
Console.WriteLine("TWENTY RANDS \t: {0}", twenty);
Console.WriteLine("TEN RANDS \t: {0}", ten);
Console.WriteLine("FIVE RANDS \t: {0}", five);
Console.WriteLine("TWO RANDS \t: {0}", two);
Console.WriteLine("ONE RANDS \t: {0}", one);
Console.WriteLine("50 CENTS \t: {0}", centsfifty);
}
}
}
There is a pattern you can use to get the amounts like this,
Here is a small example to get you started, you could probably wrap it up in a function or something, but it gives you an idea on where to start.
// number to find values from
int change = 254;
int _hundreds = 100;
int _fifty = 50;
int _twenty = 20;
int _ten = 10;
int _five = 5;
int _two = 2;
int _one = 1;
int hundreds = (int)(change / _hundreds);
int fifty = (int)((change % _hundreds) / _fifty);
int twenty = (int)(((change % _hundreds) % _fifty) / _twenty);
int ten = (int)((((change % _hundreds) % _fifty) % _twenty) / _ten);
int five = (int)(((((change % _hundreds) % _fifty) % _twenty) % _ten) / _five);
int two = (int)((((((change % _hundreds) % _fifty) % _twenty) % _ten) % _five) / _two);
int one = (int)(((((((change % _hundreds) % _fifty) % _twenty) % _ten) % _five) % _two) / _one);
Returns
hundreds = 2
fifty = 1
twenty = 0
ten = 0
five = 0
two = 2
one = 0;
One way to help simplify your code and improve it's readability is to eliminate the conditionals and
nested arithmetic operations, which almost always make the code harder to understand.
I see int is being cast too many times, this probably means it's best to use int right from the start. Eventhough you declare the cost and cashreceived variables as decimal types they are both being cast to int.
Therefore it would be better to declare both of them as int from the beginning, this will help to ease on the casting.
you may do something like this
hundreds = change / 100;
change %= 100;
fifty = change / 50;
change %= 50;
ten = change / 10;
change %= 10;
five = change / 5;
change %= 5;
two = change / 2;
change %= 2;
one = change;
Instead of
if (change >= 100)
{
hundreds = (int)change / 100;
change = (int)change % 100;
}
Try using
if (change >= 100)
{
decimal rand = change / 100;
hundred= (int)rand;
change = change % 100;
}
if (change >= 50)
{
decimal rand = (int)change / 50;
fifty = (int)rand;
change = change % 50;
}
if (change >= 20)
{
decimal rand = change / 20;
twenty = (int)rand;
change = change % 20;
}
I hope this helps.

Categories