webForumDet fria alternativet

a value of an integral type expected

.NETur .NET

16 svar · 890 visningar · startad av saw

Medlem sedan mars 20011 880 inlägg
Frågan#1

Jag vet inte riktigt vad jag gör för fel...

 public static string VardeTillTon(double Ton)
        {
            string nyTon = "";
            switch (Ton)
            {
                case 0:
                    nyTon = "C";
                    break;
                case 0.5:
                    nyTon = "C#";
                    break;
                case 1:
                    nyTon = "D";
                    break;

..felet uppkommer där Ton =0.5,2.5 osv. Jag antar att det kan bero på datatypen.
Det lustiga är att om jag gör så här...

if(Ton==0)
                nyTon = "C";
            else if (Ton == 0.5)
                nyTon = "C#";

..då fungerar det.

Ifs så skulle jag kunnat ändra allt till int och lägga till en nolla, men jag ville
gärna ha det så här.
Hur löser jag detta?

Medlem sedan dec. 20025 483 inlägg
#2

Switch-satser fungerar inte med decimaltal.

Medlem sedan mars 20011 880 inlägg
#3

Ok då vet jag det, då får jag hållad med min if-sats

Medlem sedan aug. 20039 340 inlägg
#4

Detta bör funka också.

 public static string VardeTillTon(double Ton)
        {
            string nyTon = "";
            switch ((int)(Ton*2))
            {
                case 0:
                    nyTon = "C";
                    break;
                case 1:
                    nyTon = "C#";
                    break;
                case 2:
                    nyTon = "D";
                    break;
                case 3:
                    nyTon = "D#";
                    break;
                case 4:
                    nyTon = "E";
                    break;
Medlem sedan mars 20011 880 inlägg
#5

Nej tyvärr nitro2k01 idén är ju att få med de halva stegen, det är det som det hela bygger på.

En ny fråga, vilket är det enklaste sättet att få ett kort filnamn efter openFileDialog1?
Som det nu är så får jag "C:\TEMP\Test.rtf", men skulle helst enbart ha "Test.rtf".

Medlem sedan nov. 20014 054 inlägg
#6

saw skrev:

Nej tyvärr nitro2k01 idén är ju att få med de halva stegen, det är det som det hela bygger på.

En ny fråga, vilket är det enklaste sättet att få ett kort filnamn efter openFileDialog1?
Som det nu är så får jag "C:\TEMP\Test.rtf", men skulle helst enbart ha "Test.rtf".

OpenFileDialog1.FileName

Kanske?

Medlem sedan juni 20008 205 inlägg
#7

Bara så du vet är double inte speciellt bra att använda om man vill att de ska representera exakta värden. Hur använder du värdena i andra sammanhang? Kanske finns något listigare sätt att representera dina toner.

Medlem sedan aug. 20039 340 inlägg
#8

saw skrev:

Nej tyvärr nitro2k01 idén är ju att få med de halva stegen, det är det som det hela bygger på.

Jag tror du missade vad jag gjorde. Ton*2 gör att varje halvton ligger på heltal, så D# som kommer in som 1.5 blir till 3 efter multipliceringen, och kan sedan detekteras i en switch-sats. Smart va?

Edit: Sen kan man undra varför du vill representera halvtoner som halva tal. Den representationen har egentligen bara nackdelar. I min mening borde du hellre använda ett standardiserat system. Jag rekommenderar MIDI där varje halvton motsvarar steget 1. C4 definieras som 60, och tal 0 notsvarar C-1 (C-minus 1, alltså en oktav under C0)
http://www.harmony-central.com/MIDI/Doc/table2.html

Då kan din funktion se ut exempelvis så här:

 public static string VardeTillTon(int MIDITon)
        {
            string nyTon = "";
            int oktav;
            switch (MIDITon % 12) // Använd modulu-operatorn för att ta bort oktav-skiftningen
            {
                case 0:
                    nyTon = "C";
                    break;
                case 1:
                    nyTon = "C#";
                    break;
                case 2:
                    nyTon = "D";
                    break;
                case 3:
                    nyTon = "D#";
                    break;
                case 4:
                    nyTon = "E";
                    break;
                case 5:
                    nyTon = "F";
                    break;
                case 6:
                    nyTon = "F#";
                    break;
                case 7:
                    nyTon = "G";
                    break;
                case 8:
                    nyTon = "G#";
                    break;
                case 9:
                    nyTon = "A";
                    break;
                case 10:
                    nyTon = "A#";
                    break;
                case 11:
                    nyTon = "B";
                    break;
            }
            oktav = MIDITon/12-1;
            nyTon += Convert.toString(oktav);
            return nyTon;
        }
Medlem sedan mars 20011 880 inlägg
#9

Jag är inte sämmre än att jag kan ändra mig(orsaken är gammal inlärning, att noterna
är representerade som 2,5 + 3,5) men min kära vän, jag vore väldigt tacksam om du
vill förklara

 int oktav;
            switch (MIDITon % 12) 
oktav = MIDITon/12-1;
            nyTon += Convert.toString(oktav);

Kan det betyda att A3 betraktas som ger nyTon 57 och sedan läggs 3:an till för
oktaven?

Medlem sedan mars 20011 880 inlägg
#10

Freddemannen: nej för jag tar ju mitt filnamn därifrån och då får jag med hela pathen.
Spango: Vad det är jag gör är att jag blåser liv i ett project som försvan samtidigt som
jag fick en hd-krach. Programet är helt enkelt till för att kunna transponera ackord
ifrån en dur till en annan. Samtidigt så gör jag så att en klaviatur visar ackordet och
man få höra hur det klinga.

Medlem sedan nov. 20014 054 inlägg
#11

saw skrev:

Freddemannen: nej för jag tar ju mitt filnamn därifrån och då får jag med hela pathen.

Sry.

String MyFilename;
String ShortFilename;

MyFilename = OpenFileDialog1.FileName;
ShortFilename = System.IO.Path.GetFileName(MyFilename );

Kan vara ett alternativ till att få ut endast filnamnet.

Medlem sedan mars 20011 880 inlägg
#12

Naturligtvis, tack för det Fredde Mannen.
Tillbaka till datatyper.
PGA att ni alla har talat om att jag inte skall lita på doubble, så försökte jag att ändra
till decimal när det gäller frekvenserna:

case "c4":
                    newFrekvens = 8372.018013; //osv

Om jag nu inte kan använda mig av decimal och ni säger att jag skall akta mig för
doubble, vad skall jag då ta?

Medlem sedan aug. 20039 340 inlägg
#13

saw skrev:

Jag är inte sämmre än att jag kan ändra mig(orsaken är gammal inlärning, att noterna
är representerade som 2,5 + 3,5) men min kära vän, jag vore väldigt tacksam om du
vill förklara

 int oktav;
            switch (MIDITon % 12) 
oktav = MIDITon/12-1;
            nyTon += Convert.toString(oktav);

Kan det betyda att A3 betraktas som ger nyTon 57 och sedan läggs 3:an till för
oktaven?

Modulo-operaton % gör att det första tal formateras om så att det hamnar inom en viss gräns. Exempelvis är
11%12=11 (Ingen förändring)
12%12=0
13%12=1
...
22%12=10
23%12=11
24%12=0
Divisionsrest är ett annat sätt att se på %.

Divisionen plockar ut vilken oktav som noten ligger i. -1 finns där eftersom MIDI börjar räkna från oktav -1 och inte oktav 0.

För att gå åt andra håller får du göra så här:

MIDITon = 12*(oktav+1) + Ton;

I det uttrycket så är ton och oktav åtskilda.
Oktaven justeras uppåt för att hamna rätt enligt MIDI, och Ton är en ton mellan C och B där C=0, C#=1, ... A#=10, B=11.

saw skrev:

Naturligtvis, tack för det Fredde Mannen.
Tillbaka till datatyper.
PGA att ni alla har talat om att jag inte skall lita på doubble, så försökte jag att ändra
till decimal när det gäller frekvenserna:

case "c4":
                    newFrekvens = 8372.018013; //osv

Om jag nu inte kan använda mig av decimal och ni säger att jag skall akta mig för
doubble, vad skall jag då ta?

Nej. decimal (Om det nu är så typen heter) samt double kan lagra tal med bra precision, men dålig exakthet. vad betyder det? Jo att tal kan lagras med 10 decimaler eller vad det kan vara, men däremot kan talat avvika lite lite från det exakta värdet man har angivit.
Så om man ska lagra data i så kallade diskreta steg (T ex heltalssteg) så är integer att föredra. Däremot kan du lagra frekvensen som en decimal eller double om du vill utan att oroa dig.

Medlem sedan mars 20011 880 inlägg
#14

Tack Nitro2k01 hadde jag kunnat föreslå dig till nobellpriset så skulle jag, men en
värdnadsfull bugning kommer i allafall.

Medlem sedan maj 20012 812 inlägg
#15

nitro skrev:

Nej. decimal (Om det nu är så typen heter) samt double kan lagra tal med bra precision, men dålig exakthet. vad betyder det? Jo att tal kan lagras med 10 decimaler eller vad det kan vara, men däremot kan talat avvika lite lite från det exakta värdet man har angivit.

Decimal har inte problem med exaktheten. Double däremot har problemet att du inte får tillbaka exakt det värdet som du matar in i det, men inte decimal...

- M

Medlem sedan aug. 20039 340 inlägg
#16

Gladh skrev:

nitro skrev:

Nej. decimal (Om det nu är så typen heter) samt double kan lagra tal med bra precision, men dålig exakthet. vad betyder det? Jo att tal kan lagras med 10 decimaler eller vad det kan vara, men däremot kan talat avvika lite lite från det exakta värdet man har angivit.

Decimal har inte problem med exaktheten. Double däremot har problemet att du inte får tillbaka exakt det värdet som du matar in i det, men inte decimal...

- M

Med andra ord, decimal är en fixed point-typ?
If so, I stand corrected. Jag har inte så bra koll på de olika typerna i .net.

Medlem sedan mars 20011 880 inlägg
#17

Allt är inte så enkelt...
Först vill jag visa koden.

private int grundTon = 0;
private int grundAckord = 0;
private int nyTon = 0;

//i min classfil
 public static string VardeTillTon(int MIDITon)
        {
            string nyTon = "";
            int oktav;
            switch (MIDITon % 12) // Använd modulu-operatorn för att ta bort oktav-skiftningen
            {
                case 0:
                    nyTon = "C";
                    break;
//osv blir säkert bra.
//men i visa lägen så måste jag göra tvärsom
public static int TonTillVarde(string Ton)
        {
            int nyTon = 0;
            switch (Ton)
            {
                case "C":
                    nyTon = 0;
                    break;
//här skickas då t ex C# in
//för att transponera så
grundTon = Class1.TonTillVarde(cmbOrginal.Text);
grundAckord = Class1.TonTillVarde(cmbAckord.Text);
nyTon = Class1.TonTillVarde(cmbNydur.Text);

int tempGrund = grundAckord - grundTon;
int nyTempGrund = nyTon + tempGrund;
txtNyttAckord.Text = Class1.VardeTillTon(nyTempGrund) + cmboUtokad.Text;

Mitt problem är att jag inte förstår hur jag skall hantera oktaverna.
Som det nu är så måste jag ju hålla mig inom 0 - 11.
Jag utgår ifrån att jag har missat någonting...

[edit]
Det går ju att att lägga till 60 till nyTon men det är väll kanske inte så snyggt?

148 ms totalt · 3 externa anrop · v20260731065814-full.b746b907
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
145 ms — hämta tråd, inlägg och bilagor (db)