The task description is unclear. On the one hand, you state that you want the program to ask for a float value again, until one is provided. On the other hand, you state that this should only happen when the user enters "y" or "Y", but when the user enters anything else, it should print an error message instead. This is contradictory.
If you want your program to check whether the user enters a certain character, then you must read the input as a string, instead of as a number. I recommend that you use std::getline for this.
Once you have determined that the user did not enter "Y" or "y", you can use the function std::stof to convert the string to a number.
When the user doesn't enter a number, I don't understand why you say you want to loop back to the input on "y" and "Y", but want to print an error message instead on all other inputs. However, if that is what you want, then this is how you can implement it:
#include <iostream>
#include <string>
int main()
{
    std::string input;
    float x;
    for (;;) //infinite loop, equivalent to while(1)
    {
        //prompt user for input
        std::cout << "Enter a number: ";
        //read one line of input
        std::getline( std::cin, input );
        if ( !std::cin )
            throw std::runtime_error( "unexpected stream error!" );
        //check if "y" or "Y" was entered
        if ( input == "y" || input == "Y" )
            continue;
        //attempt to convert input to a number
        try
        {
            x = std::stof( input );
        }
        catch ( std::invalid_argument )
        {
            printf( "Unable to convert to number\n" );
            break;
        }
        catch ( std::out_of_range )
        {
            printf( "Number is out of range\n" );
            break;
        }
        std::cout << "You entered the following number: " << x << "\n";
    }
}
This program works as intended (based on your contradictory description). If you enter "y" or "Y", it will loop back to the prompt for user input:
Enter a number: y
Enter a number: y
Enter a number: y
Enter a number: 67.5
You entered the following number: 67.5
If you instead provide a non-number input that is not "y" or "Y", it will print an error message, instead of looping back to the input:
Enter a number: y
Enter a number: y
Enter a number: j
unable to convert to number
This behavior does not make sense, but it appears to be what you are asking for.
This program does have one small problem, though. It will accept 6sdfjloj as valid input for the number 6:
Enter a number: 6sdfjloj
You entered the following number: 6
It would probably be more meaningful to reject such input with an error message.
Doing this is also possible, by passing a second argument to std::stof, in order to determine how many characters were converted. If not all characters were converted, you can reject the input. On the other hand, you may want to accept trailing whitespace characters (as determined by std::isspace), but reject the input if there are any other trailing characters. This would make sense: Because std::stof accepts leading whitespace characters, it makes sense to also accept trailing whitespace characters.
In my opinion, it would be more meaningful to demonstrate these programming possibilities with the following task:
The user should instead be prompted with the following message:
"Please enter a number, or enter "q" to quit: "
If the user enters "q" or "Q", the program should exit.
Otherwise, it should determine whether the user entered a valid number. If the input is a valid number, the program should say so and print the number, otherwise it should print an error message. Either way, the program should loop back to the initial prompt.
The solution to this problem would be the following:
#include <iostream>
#include <string>
#include <cctype>
int main()
{
    std::string input;
    float x;
    std::size_t pos;
    for (;;) //infinite loop, equivalent to while(1)
    {
        //prompt user for input
        std::cout << "Please enter a number, or enter \"q\" to quit: ";
        //read one line of input
        std::getline( std::cin, input );
        if ( !std::cin )
            throw std::runtime_error( "unexpected stream error!" );
        //check if "q" or "Q" was entered
        if ( input == "q" || input == "Q" )
        {
            std::cout << "Quitting program!\n";
            break;
        }
        //attempt to convert input to a number
        try
        {
            x = std::stof( input, &pos );
        }
        catch ( std::invalid_argument )
        {
            printf( "Unable to convert to number!\n" );
            continue;
        }
        catch ( std::out_of_range )
        {
            printf( "Number is out of range!\n" );
            continue;
        }
        //make sure that any trailing characters are whitespace,
        //otherwise reject input
        for ( std::size_t i = pos; input[i] != '\0'; i++ )
        {
            if ( !std::isspace( static_cast<unsigned char>(input[i]) ) )
            {
                std::cout << "Unexpected character encountered!\n";
                //we cannot use continue here, because that would jump
                //to the next iteration of the innermost loop, but we
                //want to jump to the next iteration of the outer loop
                goto continue_outer_loop;
            }
        }
        std::cout << "Input is valid, you entered the following number: " << x << "\n";
    continue_outer_loop:
        continue;
    }
}
This program has the following output:
Please enter a number, or enter "q" to quit: 67.5
Input is valid, you entered the following number: 67.5
Please enter a number, or enter "q" to quit: 32.1
Input is valid, you entered the following number: 32.1
Please enter a number, or enter "q" to quit: sdfjloj
Unable to convert to number!
Please enter a number, or enter "q" to quit: 6sdfjloj
Unexpected character encountered!
Please enter a number, or enter "q" to quit: q
Quitting program!
As you can see, it now also properly rejects input such as 6sdfjloj.
Note that this program contains one goto statement. It was appropriate to use it, in order to jump out of a nested loop. This is considered an acceptable use of goto. However, you should not use goto except in rare situations, in which there is no cleaner alternative. So please don't get used to using it.